home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / webclean / !!!python!!! / BeOpen-Python-2.0.exe / REDEMO.PY < prev    next >
Encoding:
Python Source  |  2000-10-06  |  4.5 KB  |  172 lines

  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: %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="")
  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.