]> granicus.if.org Git - python/commitdiff
New demo -- Perl style regular expression matching.
authorGuido van Rossum <guido@python.org>
Fri, 29 May 1998 19:57:47 +0000 (19:57 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 29 May 1998 19:57:47 +0000 (19:57 +0000)
Slightly more featureful than regexdemo.py.

Demo/tkinter/guido/redemo.py [new file with mode: 0644]

diff --git a/Demo/tkinter/guido/redemo.py b/Demo/tkinter/guido/redemo.py
new file mode 100644 (file)
index 0000000..1502b9d
--- /dev/null
@@ -0,0 +1,183 @@
+"""Basic regular expression demostration facility (Perl style syntax).
+
+This displays a window with two type-in boxes.  In the top box, you
+enter a Perl style regular expression.  In the bottom box, you enter a
+string.  The first match in the string of the regular expression is
+highlighted with a yellow background (or red if the match is empty --
+then the character at the match is highlighted).  The highlighting is
+continuously updated.  At the bottom are a number of checkboxes which
+control the regular expression options used (see the re module for
+descriptions).  When there's no match, or when the regular expression
+is syntactically incorrect, an error message is displayed.
+
+"""
+
+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()