By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,050 Members | 1,019 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,050 IT Pros & Developers. It's quick & easy.

Actively searching with Regular Expressions

jlm699
100+
P: 314
I have an application that is build on wxPython and have run into a small but annoying problem. I use a Search Control in my toolbar just as in the ToolBar example. Now when the user enters say PrmID[ ... this gets passed to a regular expression search function, however this obviously raises the exception saying that there is an unexpected end to the regular expression. What I would like to do is replace '[' with '\[', however using the string.replace function yields 'PrmID\\[' (escaping the escape character, but not the character I would like to have escaped). My code of what I've tried is as follows:

Expand|Select|Wrap|Line Numbers
  1.    def OnTextEntered(self, evt):
  2.         text = self.GetValue()
  3.         if re.search('\[', text) and not re.search('\]', text):
  4.             text.replace('[', '\[')
  5.         if self.DoSearch(text, evt):
  6.             if text not in self.searches:
  7.                 self.searches.append(text)
  8.                 if len(self.searches) > self.maxSearches:
  9.                     del self.searches[0]
  10.                 self.SetMenu(self.MakeMenu())
  11.  
And the doSearch function...
Expand|Select|Wrap|Line Numbers
  1.     def DoSearch(self,  text, event=None):
  2.         if not len(self.data_bak):
  3.             return False
  4.  
  5.         # 10014 is the Event type for wx.EVT_MENU
  6.         # 10164 is the Event type for wx.EVT_TEXT (adaptive search)
  7.         # 10165 is the Event type for wx.EVT_TEXT_ENTER
  8.         valid_events = [10014, 10165]
  9.  
  10.         regex = re.compile(text.upper())
  11.         tool = self.tb.FindById(Global.OnTB_ActSearch_Id)
  12.         if tool.IsToggled():
  13.             self.lc.DeleteAllItems()
  14.             for entry in range(len(self.data_bak)):
  15.                 if text:
  16.                     if regex.search(self.data_bak[entry][0].upper()):
  17.                         self.lc.Append(self.data_bak[entry])
  18.                 else:
  19.                     self.lc.Append(self.data_bak[entry])
  20.             return False
  21.         elif not tool.IsToggled() and event.GetEventType() in valid_events:
  22.             idx = self.lc.FindItem(self.currentItem + 1, text, True)
  23.             if idx != -1:
  24.                 self.lc.Focus(idx)
  25.                 self.lc.Select(idx)
  26.             return True
  27.  
BTW, basically this application has a listing of Parameter names and values in a ListControl (self.lc), which when initially opened is backed-up by a two-dimensional array (self.data_bak).
This 'active search' will modify what the user sees in the listctrl (making sure to update the back-up as well), just as they type it (I wanted to reproduce the Search function from the upper right corner of iTunes). The toggle check is there because the user has a toggle button on the toolbar to turn this active search on or off.
So if anybody has any ideas as to how to replace '[' in a string with literally '\[' I would appreciate it. I've played around with raw strings and even tried using a crazy combination of raw strings and the repr function to no avail.

An example of parameter names is P_SWID_PrmID[0].

To reiterate, I simply need to take the user input and escape any bracket characters so that the regex.search function does not mistake it for the start/end of a regular expression character class.
Jul 30 '07 #1
Share this Question
Share on Google+
3 Replies


bartonc
Expert 5K+
P: 6,596
I'm not too familiar with regular expressions yet, but how 'buot making a character class of one character? re doesn't mind the the syntax of this pattern:
Expand|Select|Wrap|Line Numbers
  1. import re
  2. >>> s = 'PrmID['
  3. >>> re.sub('[[]', '[', s)
  4. 'PrmID['
  5. >>> 
So, it seems that you could use:
Expand|Select|Wrap|Line Numbers
  1. s.replace('[', '[[]')
Jul 30 '07 #2

bvdet
Expert Mod 2.5K+
P: 2,851
I'm not too familiar with regular expressions yet, but how 'buot making a character class of one character? re doesn't mind the the syntax of this pattern:
Expand|Select|Wrap|Line Numbers
  1. import re
  2. >>> s = 'PrmID['
  3. >>> re.sub('[[]', '[', s)
  4. 'PrmID['
  5. >>> 
So, it seems that you could use:
Expand|Select|Wrap|Line Numbers
  1. s.replace('[', '[[]')
Good point Barton. I checked it out also:
Expand|Select|Wrap|Line Numbers
  1. >>> s = 'P_SWID_PrmID[0]'
  2. >>> searchStr = 'Prmid['
  3. >>> import re
  4. >>> patt = re.compile(searchStr.replace('[', '[[]'), re.IGNORECASE)
  5. >>> m = patt.search(s)
  6. >>> m
  7. <_sre.SRE_Match object at 0x00D5A9C0>
  8. >>> patt = re.compile(searchStr, re.IGNORECASE)
  9. Traceback (most recent call last):
  10.   File "<interactive input>", line 1, in ?
  11.   File "C:\Python23\lib\sre.py", line 179, in compile
  12.     return _compile(pattern, flags)
  13.   File "C:\Python23\lib\sre.py", line 230, in _compile
  14.     raise error, v # invalid expression
  15. error: unexpected end of regular expression
  16. >>> patt.findall(s)
  17. ['PrmID[']
  18. >>> 
Jul 31 '07 #3

jlm699
100+
P: 314
Wow, thanks guys! That's elegant yet so simple! I was lazy and just replaced every occurance of '[' or ']' with '.' (I figured, if the user knows that much of the name they'll know the number contained within the brackets so actually finding a match to the bracket wasn't too terribly important)

But thanks for the great suggestions!
Aug 9 '07 #4

Post your reply

Sign in to post your reply or Sign up for a free account.