blob: 2b5ade44aa202a4fd5dd9b59d520b6dffe4bc364 [file] [log] [blame]
Éric Araujo0fb681e2011-07-29 12:06:13 +02001#!/usr/bin/env python
Guido van Rossum70280b82000-10-06 17:37:12 +00002"""Basic regular expression demostration facility (Perl style syntax)."""
3
4from Tkinter import *
5import re
6
7class ReDemo:
Guido van Rossum70280b82000-10-06 17:37:12 +00008
Tim Peters70c43782001-01-17 08:48:39 +00009 def __init__(self, master):
10 self.master = master
Guido van Rossum70280b82000-10-06 17:37:12 +000011
Tim Peters70c43782001-01-17 08:48:39 +000012 self.promptdisplay = Label(self.master, anchor=W,
13 text="Enter a Perl-style regular expression:")
14 self.promptdisplay.pack(side=TOP, fill=X)
Guido van Rossum70280b82000-10-06 17:37:12 +000015
Tim Peters70c43782001-01-17 08:48:39 +000016 self.regexdisplay = Entry(self.master)
17 self.regexdisplay.pack(fill=X)
18 self.regexdisplay.focus_set()
Guido van Rossum70280b82000-10-06 17:37:12 +000019
Tim Peters70c43782001-01-17 08:48:39 +000020 self.addoptions()
Guido van Rossum70280b82000-10-06 17:37:12 +000021
Tim Peters70c43782001-01-17 08:48:39 +000022 self.statusdisplay = Label(self.master, text="", anchor=W)
23 self.statusdisplay.pack(side=TOP, fill=X)
Guido van Rossum70280b82000-10-06 17:37:12 +000024
Tim Peters70c43782001-01-17 08:48:39 +000025 self.labeldisplay = Label(self.master, anchor=W,
26 text="Enter a string to search:")
27 self.labeldisplay.pack(fill=X)
28 self.labeldisplay.pack(fill=X)
Guido van Rossum70280b82000-10-06 17:37:12 +000029
Tim Peters70c43782001-01-17 08:48:39 +000030 self.showframe = Frame(master)
31 self.showframe.pack(fill=X, anchor=W)
Guido van Rossum70280b82000-10-06 17:37:12 +000032
Tim Peters70c43782001-01-17 08:48:39 +000033 self.showvar = StringVar(master)
34 self.showvar.set("first")
Guido van Rossum70280b82000-10-06 17:37:12 +000035
Tim Peters70c43782001-01-17 08:48:39 +000036 self.showfirstradio = Radiobutton(self.showframe,
37 text="Highlight first match",
38 variable=self.showvar,
39 value="first",
40 command=self.recompile)
41 self.showfirstradio.pack(side=LEFT)
Guido van Rossum70280b82000-10-06 17:37:12 +000042
Tim Peters70c43782001-01-17 08:48:39 +000043 self.showallradio = Radiobutton(self.showframe,
44 text="Highlight all matches",
45 variable=self.showvar,
46 value="all",
47 command=self.recompile)
48 self.showallradio.pack(side=LEFT)
Guido van Rossum70280b82000-10-06 17:37:12 +000049
Tim Peters70c43782001-01-17 08:48:39 +000050 self.stringdisplay = Text(self.master, width=60, height=4)
51 self.stringdisplay.pack(fill=BOTH, expand=1)
52 self.stringdisplay.tag_configure("hit", background="yellow")
Guido van Rossum70280b82000-10-06 17:37:12 +000053
Tim Peters70c43782001-01-17 08:48:39 +000054 self.grouplabel = Label(self.master, text="Groups:", anchor=W)
55 self.grouplabel.pack(fill=X)
Guido van Rossum70280b82000-10-06 17:37:12 +000056
Tim Peters70c43782001-01-17 08:48:39 +000057 self.grouplist = Listbox(self.master)
58 self.grouplist.pack(expand=1, fill=BOTH)
Guido van Rossum70280b82000-10-06 17:37:12 +000059
Tim Peters70c43782001-01-17 08:48:39 +000060 self.regexdisplay.bind('<Key>', self.recompile)
61 self.stringdisplay.bind('<Key>', self.reevaluate)
Guido van Rossum70280b82000-10-06 17:37:12 +000062
Tim Peters70c43782001-01-17 08:48:39 +000063 self.compiled = None
64 self.recompile()
Guido van Rossum70280b82000-10-06 17:37:12 +000065
Tim Peters70c43782001-01-17 08:48:39 +000066 btags = self.regexdisplay.bindtags()
67 self.regexdisplay.bindtags(btags[1:] + btags[:1])
Guido van Rossum70280b82000-10-06 17:37:12 +000068
Tim Peters70c43782001-01-17 08:48:39 +000069 btags = self.stringdisplay.bindtags()
70 self.stringdisplay.bindtags(btags[1:] + btags[:1])
71
72 def addoptions(self):
73 self.frames = []
74 self.boxes = []
75 self.vars = []
76 for name in ('IGNORECASE',
77 'LOCALE',
78 'MULTILINE',
79 'DOTALL',
80 'VERBOSE'):
81 if len(self.boxes) % 3 == 0:
82 frame = Frame(self.master)
83 frame.pack(fill=X)
84 self.frames.append(frame)
85 val = getattr(re, name)
86 var = IntVar()
87 box = Checkbutton(frame,
88 variable=var, text=name,
89 offvalue=0, onvalue=val,
90 command=self.recompile)
91 box.pack(side=LEFT)
92 self.boxes.append(box)
93 self.vars.append(var)
94
95 def getflags(self):
96 flags = 0
97 for var in self.vars:
98 flags = flags | var.get()
99 flags = flags
100 return flags
101
102 def recompile(self, event=None):
103 try:
104 self.compiled = re.compile(self.regexdisplay.get(),
105 self.getflags())
106 bg = self.promptdisplay['background']
107 self.statusdisplay.config(text="", background=bg)
108 except re.error, msg:
109 self.compiled = None
110 self.statusdisplay.config(
111 text="re.error: %s" % str(msg),
112 background="red")
113 self.reevaluate()
114
115 def reevaluate(self, event=None):
116 try:
117 self.stringdisplay.tag_remove("hit", "1.0", END)
118 except TclError:
119 pass
120 try:
121 self.stringdisplay.tag_remove("hit0", "1.0", END)
122 except TclError:
123 pass
124 self.grouplist.delete(0, END)
125 if not self.compiled:
126 return
127 self.stringdisplay.tag_configure("hit", background="yellow")
128 self.stringdisplay.tag_configure("hit0", background="orange")
129 text = self.stringdisplay.get("1.0", END)
130 last = 0
131 nmatches = 0
132 while last <= len(text):
133 m = self.compiled.search(text, last)
134 if m is None:
135 break
136 first, last = m.span()
137 if last == first:
138 last = first+1
139 tag = "hit0"
140 else:
141 tag = "hit"
142 pfirst = "1.0 + %d chars" % first
143 plast = "1.0 + %d chars" % last
144 self.stringdisplay.tag_add(tag, pfirst, plast)
145 if nmatches == 0:
146 self.stringdisplay.yview_pickplace(pfirst)
147 groups = list(m.groups())
148 groups.insert(0, m.group())
149 for i in range(len(groups)):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000150 g = "%2d: %r" % (i, groups[i])
Tim Peters70c43782001-01-17 08:48:39 +0000151 self.grouplist.insert(END, g)
152 nmatches = nmatches + 1
153 if self.showvar.get() == "first":
154 break
155
156 if nmatches == 0:
157 self.statusdisplay.config(text="(no match)",
158 background="yellow")
159 else:
160 self.statusdisplay.config(text="")
Guido van Rossum70280b82000-10-06 17:37:12 +0000161
162
163# Main function, run when invoked as a stand-alone Python program.
164
165def main():
166 root = Tk()
167 demo = ReDemo(root)
168 root.protocol('WM_DELETE_WINDOW', root.quit)
169 root.mainloop()
170
171if __name__ == '__main__':
172 main()