blob: 1eed8f845c04b2d3fded4b69e2e6ec8f2d9d4528 [file] [log] [blame]
Guido van Rossum70280b82000-10-06 17:37:12 +00001"""Basic regular expression demostration facility (Perl style syntax)."""
2
3from Tkinter import *
4import re
5
6class ReDemo:
Guido van Rossum70280b82000-10-06 17:37:12 +00007
Tim Peters70c43782001-01-17 08:48:39 +00008 def __init__(self, master):
9 self.master = master
Guido van Rossum70280b82000-10-06 17:37:12 +000010
Tim Peters70c43782001-01-17 08:48:39 +000011 self.promptdisplay = Label(self.master, anchor=W,
12 text="Enter a Perl-style regular expression:")
13 self.promptdisplay.pack(side=TOP, fill=X)
Guido van Rossum70280b82000-10-06 17:37:12 +000014
Tim Peters70c43782001-01-17 08:48:39 +000015 self.regexdisplay = Entry(self.master)
16 self.regexdisplay.pack(fill=X)
17 self.regexdisplay.focus_set()
Guido van Rossum70280b82000-10-06 17:37:12 +000018
Tim Peters70c43782001-01-17 08:48:39 +000019 self.addoptions()
Guido van Rossum70280b82000-10-06 17:37:12 +000020
Tim Peters70c43782001-01-17 08:48:39 +000021 self.statusdisplay = Label(self.master, text="", anchor=W)
22 self.statusdisplay.pack(side=TOP, fill=X)
Guido van Rossum70280b82000-10-06 17:37:12 +000023
Tim Peters70c43782001-01-17 08:48:39 +000024 self.labeldisplay = Label(self.master, anchor=W,
25 text="Enter a string to search:")
26 self.labeldisplay.pack(fill=X)
27 self.labeldisplay.pack(fill=X)
Guido van Rossum70280b82000-10-06 17:37:12 +000028
Tim Peters70c43782001-01-17 08:48:39 +000029 self.showframe = Frame(master)
30 self.showframe.pack(fill=X, anchor=W)
Guido van Rossum70280b82000-10-06 17:37:12 +000031
Tim Peters70c43782001-01-17 08:48:39 +000032 self.showvar = StringVar(master)
33 self.showvar.set("first")
Guido van Rossum70280b82000-10-06 17:37:12 +000034
Tim Peters70c43782001-01-17 08:48:39 +000035 self.showfirstradio = Radiobutton(self.showframe,
36 text="Highlight first match",
37 variable=self.showvar,
38 value="first",
39 command=self.recompile)
40 self.showfirstradio.pack(side=LEFT)
Guido van Rossum70280b82000-10-06 17:37:12 +000041
Tim Peters70c43782001-01-17 08:48:39 +000042 self.showallradio = Radiobutton(self.showframe,
43 text="Highlight all matches",
44 variable=self.showvar,
45 value="all",
46 command=self.recompile)
47 self.showallradio.pack(side=LEFT)
Guido van Rossum70280b82000-10-06 17:37:12 +000048
Tim Peters70c43782001-01-17 08:48:39 +000049 self.stringdisplay = Text(self.master, width=60, height=4)
50 self.stringdisplay.pack(fill=BOTH, expand=1)
51 self.stringdisplay.tag_configure("hit", background="yellow")
Guido van Rossum70280b82000-10-06 17:37:12 +000052
Tim Peters70c43782001-01-17 08:48:39 +000053 self.grouplabel = Label(self.master, text="Groups:", anchor=W)
54 self.grouplabel.pack(fill=X)
Guido van Rossum70280b82000-10-06 17:37:12 +000055
Tim Peters70c43782001-01-17 08:48:39 +000056 self.grouplist = Listbox(self.master)
57 self.grouplist.pack(expand=1, fill=BOTH)
Guido van Rossum70280b82000-10-06 17:37:12 +000058
Tim Peters70c43782001-01-17 08:48:39 +000059 self.regexdisplay.bind('<Key>', self.recompile)
60 self.stringdisplay.bind('<Key>', self.reevaluate)
Guido van Rossum70280b82000-10-06 17:37:12 +000061
Tim Peters70c43782001-01-17 08:48:39 +000062 self.compiled = None
63 self.recompile()
Guido van Rossum70280b82000-10-06 17:37:12 +000064
Tim Peters70c43782001-01-17 08:48:39 +000065 btags = self.regexdisplay.bindtags()
66 self.regexdisplay.bindtags(btags[1:] + btags[:1])
Guido van Rossum70280b82000-10-06 17:37:12 +000067
Tim Peters70c43782001-01-17 08:48:39 +000068 btags = self.stringdisplay.bindtags()
69 self.stringdisplay.bindtags(btags[1:] + btags[:1])
70
71 def addoptions(self):
72 self.frames = []
73 self.boxes = []
74 self.vars = []
75 for name in ('IGNORECASE',
76 'LOCALE',
77 'MULTILINE',
78 'DOTALL',
79 'VERBOSE'):
80 if len(self.boxes) % 3 == 0:
81 frame = Frame(self.master)
82 frame.pack(fill=X)
83 self.frames.append(frame)
84 val = getattr(re, name)
85 var = IntVar()
86 box = Checkbutton(frame,
87 variable=var, text=name,
88 offvalue=0, onvalue=val,
89 command=self.recompile)
90 box.pack(side=LEFT)
91 self.boxes.append(box)
92 self.vars.append(var)
93
94 def getflags(self):
95 flags = 0
96 for var in self.vars:
97 flags = flags | var.get()
98 flags = flags
99 return flags
100
101 def recompile(self, event=None):
102 try:
103 self.compiled = re.compile(self.regexdisplay.get(),
104 self.getflags())
105 bg = self.promptdisplay['background']
106 self.statusdisplay.config(text="", background=bg)
107 except re.error, msg:
108 self.compiled = None
109 self.statusdisplay.config(
110 text="re.error: %s" % str(msg),
111 background="red")
112 self.reevaluate()
113
114 def reevaluate(self, event=None):
115 try:
116 self.stringdisplay.tag_remove("hit", "1.0", END)
117 except TclError:
118 pass
119 try:
120 self.stringdisplay.tag_remove("hit0", "1.0", END)
121 except TclError:
122 pass
123 self.grouplist.delete(0, END)
124 if not self.compiled:
125 return
126 self.stringdisplay.tag_configure("hit", background="yellow")
127 self.stringdisplay.tag_configure("hit0", background="orange")
128 text = self.stringdisplay.get("1.0", END)
129 last = 0
130 nmatches = 0
131 while last <= len(text):
132 m = self.compiled.search(text, last)
133 if m is None:
134 break
135 first, last = m.span()
136 if last == first:
137 last = first+1
138 tag = "hit0"
139 else:
140 tag = "hit"
141 pfirst = "1.0 + %d chars" % first
142 plast = "1.0 + %d chars" % last
143 self.stringdisplay.tag_add(tag, pfirst, plast)
144 if nmatches == 0:
145 self.stringdisplay.yview_pickplace(pfirst)
146 groups = list(m.groups())
147 groups.insert(0, m.group())
148 for i in range(len(groups)):
149 g = "%2d: %s" % (i, `groups[i]`)
150 self.grouplist.insert(END, g)
151 nmatches = nmatches + 1
152 if self.showvar.get() == "first":
153 break
154
155 if nmatches == 0:
156 self.statusdisplay.config(text="(no match)",
157 background="yellow")
158 else:
159 self.statusdisplay.config(text="")
Guido van Rossum70280b82000-10-06 17:37:12 +0000160
161
162# Main function, run when invoked as a stand-alone Python program.
163
164def main():
165 root = Tk()
166 demo = ReDemo(root)
167 root.protocol('WM_DELETE_WINDOW', root.quit)
168 root.mainloop()
169
170if __name__ == '__main__':
171 main()