]>
Commit | Line | Data |
---|---|---|
4710c53d | 1 | """Basic regular expression demostration facility (Perl style syntax)."""\r |
2 | \r | |
3 | from Tkinter import *\r | |
4 | import re\r | |
5 | \r | |
6 | class ReDemo:\r | |
7 | \r | |
8 | def __init__(self, master):\r | |
9 | self.master = master\r | |
10 | \r | |
11 | self.promptdisplay = Label(self.master, anchor=W,\r | |
12 | text="Enter a Perl-style regular expression:")\r | |
13 | self.promptdisplay.pack(side=TOP, fill=X)\r | |
14 | \r | |
15 | self.regexdisplay = Entry(self.master)\r | |
16 | self.regexdisplay.pack(fill=X)\r | |
17 | self.regexdisplay.focus_set()\r | |
18 | \r | |
19 | self.addoptions()\r | |
20 | \r | |
21 | self.statusdisplay = Label(self.master, text="", anchor=W)\r | |
22 | self.statusdisplay.pack(side=TOP, fill=X)\r | |
23 | \r | |
24 | self.labeldisplay = Label(self.master, anchor=W,\r | |
25 | text="Enter a string to search:")\r | |
26 | self.labeldisplay.pack(fill=X)\r | |
27 | self.labeldisplay.pack(fill=X)\r | |
28 | \r | |
29 | self.showframe = Frame(master)\r | |
30 | self.showframe.pack(fill=X, anchor=W)\r | |
31 | \r | |
32 | self.showvar = StringVar(master)\r | |
33 | self.showvar.set("first")\r | |
34 | \r | |
35 | self.showfirstradio = Radiobutton(self.showframe,\r | |
36 | text="Highlight first match",\r | |
37 | variable=self.showvar,\r | |
38 | value="first",\r | |
39 | command=self.recompile)\r | |
40 | self.showfirstradio.pack(side=LEFT)\r | |
41 | \r | |
42 | self.showallradio = Radiobutton(self.showframe,\r | |
43 | text="Highlight all matches",\r | |
44 | variable=self.showvar,\r | |
45 | value="all",\r | |
46 | command=self.recompile)\r | |
47 | self.showallradio.pack(side=LEFT)\r | |
48 | \r | |
49 | self.stringdisplay = Text(self.master, width=60, height=4)\r | |
50 | self.stringdisplay.pack(fill=BOTH, expand=1)\r | |
51 | self.stringdisplay.tag_configure("hit", background="yellow")\r | |
52 | \r | |
53 | self.grouplabel = Label(self.master, text="Groups:", anchor=W)\r | |
54 | self.grouplabel.pack(fill=X)\r | |
55 | \r | |
56 | self.grouplist = Listbox(self.master)\r | |
57 | self.grouplist.pack(expand=1, fill=BOTH)\r | |
58 | \r | |
59 | self.regexdisplay.bind('<Key>', self.recompile)\r | |
60 | self.stringdisplay.bind('<Key>', self.reevaluate)\r | |
61 | \r | |
62 | self.compiled = None\r | |
63 | self.recompile()\r | |
64 | \r | |
65 | btags = self.regexdisplay.bindtags()\r | |
66 | self.regexdisplay.bindtags(btags[1:] + btags[:1])\r | |
67 | \r | |
68 | btags = self.stringdisplay.bindtags()\r | |
69 | self.stringdisplay.bindtags(btags[1:] + btags[:1])\r | |
70 | \r | |
71 | def addoptions(self):\r | |
72 | self.frames = []\r | |
73 | self.boxes = []\r | |
74 | self.vars = []\r | |
75 | for name in ('IGNORECASE',\r | |
76 | 'LOCALE',\r | |
77 | 'MULTILINE',\r | |
78 | 'DOTALL',\r | |
79 | 'VERBOSE'):\r | |
80 | if len(self.boxes) % 3 == 0:\r | |
81 | frame = Frame(self.master)\r | |
82 | frame.pack(fill=X)\r | |
83 | self.frames.append(frame)\r | |
84 | val = getattr(re, name)\r | |
85 | var = IntVar()\r | |
86 | box = Checkbutton(frame,\r | |
87 | variable=var, text=name,\r | |
88 | offvalue=0, onvalue=val,\r | |
89 | command=self.recompile)\r | |
90 | box.pack(side=LEFT)\r | |
91 | self.boxes.append(box)\r | |
92 | self.vars.append(var)\r | |
93 | \r | |
94 | def getflags(self):\r | |
95 | flags = 0\r | |
96 | for var in self.vars:\r | |
97 | flags = flags | var.get()\r | |
98 | flags = flags\r | |
99 | return flags\r | |
100 | \r | |
101 | def recompile(self, event=None):\r | |
102 | try:\r | |
103 | self.compiled = re.compile(self.regexdisplay.get(),\r | |
104 | self.getflags())\r | |
105 | bg = self.promptdisplay['background']\r | |
106 | self.statusdisplay.config(text="", background=bg)\r | |
107 | except re.error, msg:\r | |
108 | self.compiled = None\r | |
109 | self.statusdisplay.config(\r | |
110 | text="re.error: %s" % str(msg),\r | |
111 | background="red")\r | |
112 | self.reevaluate()\r | |
113 | \r | |
114 | def reevaluate(self, event=None):\r | |
115 | try:\r | |
116 | self.stringdisplay.tag_remove("hit", "1.0", END)\r | |
117 | except TclError:\r | |
118 | pass\r | |
119 | try:\r | |
120 | self.stringdisplay.tag_remove("hit0", "1.0", END)\r | |
121 | except TclError:\r | |
122 | pass\r | |
123 | self.grouplist.delete(0, END)\r | |
124 | if not self.compiled:\r | |
125 | return\r | |
126 | self.stringdisplay.tag_configure("hit", background="yellow")\r | |
127 | self.stringdisplay.tag_configure("hit0", background="orange")\r | |
128 | text = self.stringdisplay.get("1.0", END)\r | |
129 | last = 0\r | |
130 | nmatches = 0\r | |
131 | while last <= len(text):\r | |
132 | m = self.compiled.search(text, last)\r | |
133 | if m is None:\r | |
134 | break\r | |
135 | first, last = m.span()\r | |
136 | if last == first:\r | |
137 | last = first+1\r | |
138 | tag = "hit0"\r | |
139 | else:\r | |
140 | tag = "hit"\r | |
141 | pfirst = "1.0 + %d chars" % first\r | |
142 | plast = "1.0 + %d chars" % last\r | |
143 | self.stringdisplay.tag_add(tag, pfirst, plast)\r | |
144 | if nmatches == 0:\r | |
145 | self.stringdisplay.yview_pickplace(pfirst)\r | |
146 | groups = list(m.groups())\r | |
147 | groups.insert(0, m.group())\r | |
148 | for i in range(len(groups)):\r | |
149 | g = "%2d: %r" % (i, groups[i])\r | |
150 | self.grouplist.insert(END, g)\r | |
151 | nmatches = nmatches + 1\r | |
152 | if self.showvar.get() == "first":\r | |
153 | break\r | |
154 | \r | |
155 | if nmatches == 0:\r | |
156 | self.statusdisplay.config(text="(no match)",\r | |
157 | background="yellow")\r | |
158 | else:\r | |
159 | self.statusdisplay.config(text="")\r | |
160 | \r | |
161 | \r | |
162 | # Main function, run when invoked as a stand-alone Python program.\r | |
163 | \r | |
164 | def main():\r | |
165 | root = Tk()\r | |
166 | demo = ReDemo(root)\r | |
167 | root.protocol('WM_DELETE_WINDOW', root.quit)\r | |
168 | root.mainloop()\r | |
169 | \r | |
170 | if __name__ == '__main__':\r | |
171 | main()\r |