Home | History | Annotate | Download | only in scripts
      1 """Basic regular expression demostration facility (Perl style syntax)."""
      2 
      3 from Tkinter import *
      4 import re
      5 
      6 class ReDemo:
      7 
      8     def __init__(self, master):
      9         self.master = master
     10 
     11         self.promptdisplay = Label(self.master, anchor=W,
     12                 text="Enter a Perl-style regular expression:")
     13         self.promptdisplay.pack(side=TOP, fill=X)
     14 
     15         self.regexdisplay = Entry(self.master)
     16         self.regexdisplay.pack(fill=X)
     17         self.regexdisplay.focus_set()
     18 
     19         self.addoptions()
     20 
     21         self.statusdisplay = Label(self.master, text="", anchor=W)
     22         self.statusdisplay.pack(side=TOP, fill=X)
     23 
     24         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)
     28 
     29         self.showframe = Frame(master)
     30         self.showframe.pack(fill=X, anchor=W)
     31 
     32         self.showvar = StringVar(master)
     33         self.showvar.set("first")
     34 
     35         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)
     41 
     42         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)
     48 
     49         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")
     52 
     53         self.grouplabel = Label(self.master, text="Groups:", anchor=W)
     54         self.grouplabel.pack(fill=X)
     55 
     56         self.grouplist = Listbox(self.master)
     57         self.grouplist.pack(expand=1, fill=BOTH)
     58 
     59         self.regexdisplay.bind('<Key>', self.recompile)
     60         self.stringdisplay.bind('<Key>', self.reevaluate)
     61 
     62         self.compiled = None
     63         self.recompile()
     64 
     65         btags = self.regexdisplay.bindtags()
     66         self.regexdisplay.bindtags(btags[1:] + btags[:1])
     67 
     68         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: %r" % (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="")
    160 
    161 
    162 # Main function, run when invoked as a stand-alone Python program.

    163 
    164 def main():
    165     root = Tk()
    166     demo = ReDemo(root)
    167     root.protocol('WM_DELETE_WINDOW', root.quit)
    168     root.mainloop()
    169 
    170 if __name__ == '__main__':
    171     main()
    172