mirror of
https://github.com/python/cpython.git
synced 2025-07-25 20:24:11 +00:00

somewhat useful to learn regular expressions, and this way it'll be installed on Windows. This closes bug report 115609.
171 lines
4.4 KiB
Python
171 lines
4.4 KiB
Python
"""Basic regular expression demostration facility (Perl style syntax)."""
|
|
|
|
from Tkinter import *
|
|
import re
|
|
|
|
class ReDemo:
|
|
|
|
def __init__(self, master):
|
|
self.master = master
|
|
|
|
self.promptdisplay = Label(self.master, anchor=W,
|
|
text="Enter a Perl-style regular expression:")
|
|
self.promptdisplay.pack(side=TOP, fill=X)
|
|
|
|
self.regexdisplay = Entry(self.master)
|
|
self.regexdisplay.pack(fill=X)
|
|
self.regexdisplay.focus_set()
|
|
|
|
self.addoptions()
|
|
|
|
self.statusdisplay = Label(self.master, text="", anchor=W)
|
|
self.statusdisplay.pack(side=TOP, fill=X)
|
|
|
|
self.labeldisplay = Label(self.master, anchor=W,
|
|
text="Enter a string to search:")
|
|
self.labeldisplay.pack(fill=X)
|
|
self.labeldisplay.pack(fill=X)
|
|
|
|
self.showframe = Frame(master)
|
|
self.showframe.pack(fill=X, anchor=W)
|
|
|
|
self.showvar = StringVar(master)
|
|
self.showvar.set("first")
|
|
|
|
self.showfirstradio = Radiobutton(self.showframe,
|
|
text="Highlight first match",
|
|
variable=self.showvar,
|
|
value="first",
|
|
command=self.recompile)
|
|
self.showfirstradio.pack(side=LEFT)
|
|
|
|
self.showallradio = Radiobutton(self.showframe,
|
|
text="Highlight all matches",
|
|
variable=self.showvar,
|
|
value="all",
|
|
command=self.recompile)
|
|
self.showallradio.pack(side=LEFT)
|
|
|
|
self.stringdisplay = Text(self.master, width=60, height=4)
|
|
self.stringdisplay.pack(fill=BOTH, expand=1)
|
|
self.stringdisplay.tag_configure("hit", background="yellow")
|
|
|
|
self.grouplabel = Label(self.master, text="Groups:", anchor=W)
|
|
self.grouplabel.pack(fill=X)
|
|
|
|
self.grouplist = Listbox(self.master)
|
|
self.grouplist.pack(expand=1, fill=BOTH)
|
|
|
|
self.regexdisplay.bind('<Key>', self.recompile)
|
|
self.stringdisplay.bind('<Key>', self.reevaluate)
|
|
|
|
self.compiled = None
|
|
self.recompile()
|
|
|
|
btags = self.regexdisplay.bindtags()
|
|
self.regexdisplay.bindtags(btags[1:] + btags[:1])
|
|
|
|
btags = self.stringdisplay.bindtags()
|
|
self.stringdisplay.bindtags(btags[1:] + btags[:1])
|
|
|
|
def addoptions(self):
|
|
self.frames = []
|
|
self.boxes = []
|
|
self.vars = []
|
|
for name in ('IGNORECASE',
|
|
'LOCALE',
|
|
'MULTILINE',
|
|
'DOTALL',
|
|
'VERBOSE'):
|
|
if len(self.boxes) % 3 == 0:
|
|
frame = Frame(self.master)
|
|
frame.pack(fill=X)
|
|
self.frames.append(frame)
|
|
val = getattr(re, name)
|
|
var = IntVar()
|
|
box = Checkbutton(frame,
|
|
variable=var, text=name,
|
|
offvalue=0, onvalue=val,
|
|
command=self.recompile)
|
|
box.pack(side=LEFT)
|
|
self.boxes.append(box)
|
|
self.vars.append(var)
|
|
|
|
def getflags(self):
|
|
flags = 0
|
|
for var in self.vars:
|
|
flags = flags | var.get()
|
|
flags = flags
|
|
return flags
|
|
|
|
def recompile(self, event=None):
|
|
try:
|
|
self.compiled = re.compile(self.regexdisplay.get(),
|
|
self.getflags())
|
|
bg = self.promptdisplay['background']
|
|
self.statusdisplay.config(text="", background=bg)
|
|
except re.error, msg:
|
|
self.compiled = None
|
|
self.statusdisplay.config(
|
|
text="re.error: %s" % str(msg),
|
|
background="red")
|
|
self.reevaluate()
|
|
|
|
def reevaluate(self, event=None):
|
|
try:
|
|
self.stringdisplay.tag_remove("hit", "1.0", END)
|
|
except TclError:
|
|
pass
|
|
try:
|
|
self.stringdisplay.tag_remove("hit0", "1.0", END)
|
|
except TclError:
|
|
pass
|
|
self.grouplist.delete(0, END)
|
|
if not self.compiled:
|
|
return
|
|
self.stringdisplay.tag_configure("hit", background="yellow")
|
|
self.stringdisplay.tag_configure("hit0", background="orange")
|
|
text = self.stringdisplay.get("1.0", END)
|
|
last = 0
|
|
nmatches = 0
|
|
while last <= len(text):
|
|
m = self.compiled.search(text, last)
|
|
if m is None:
|
|
break
|
|
first, last = m.span()
|
|
if last == first:
|
|
last = first+1
|
|
tag = "hit0"
|
|
else:
|
|
tag = "hit"
|
|
pfirst = "1.0 + %d chars" % first
|
|
plast = "1.0 + %d chars" % last
|
|
self.stringdisplay.tag_add(tag, pfirst, plast)
|
|
if nmatches == 0:
|
|
self.stringdisplay.yview_pickplace(pfirst)
|
|
groups = list(m.groups())
|
|
groups.insert(0, m.group())
|
|
for i in range(len(groups)):
|
|
g = "%2d: %s" % (i, `groups[i]`)
|
|
self.grouplist.insert(END, g)
|
|
nmatches = nmatches + 1
|
|
if self.showvar.get() == "first":
|
|
break
|
|
|
|
if nmatches == 0:
|
|
self.statusdisplay.config(text="(no match)",
|
|
background="yellow")
|
|
else:
|
|
self.statusdisplay.config(text="")
|
|
|
|
|
|
# Main function, run when invoked as a stand-alone Python program.
|
|
|
|
def main():
|
|
root = Tk()
|
|
demo = ReDemo(root)
|
|
root.protocol('WM_DELETE_WINDOW', root.quit)
|
|
root.mainloop()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|