Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Don't want to do the regexp test twice

Reply
Thread Tools

Re: Don't want to do the regexp test twice

 
 
Bengt Richter
Guest
Posts: n/a
 
      07-25-2003
On Thu, 24 Jul 2003 23:44:57 +0200, Egbert Bouwman <> wrote:

>While looping over a long list (with file records)
>I use an (also long) if..elif sequence.
>One of these elif's tests a regular expression, and
>if the test succeeds, I want to use a part of the match.
>Something like this:
>
>pat = re.compile(r'...')
>for line in mylist:
> if ... :
> ....
> elif ... :
> ....
> elif pat.search(line):
> mat = pat.search(line)
> elif ... :
> ...
> else ...:
> ...
>Is there a way to to do this job with only one pat.search(line) ?

Hack #1 (list comprehension abuse):

>>> import re
>>> pat = re.compile(r'...')
>>> mylist = ' a bc def ghij'.split(' ')
>>> mylist

['', 'a', 'bc', 'def', 'ghij']
>>> for line in mylist:

... if 1==2: 'naw'
... elif 3==4: 'neither'
... elif [1 for mat in [pat.search(line)] if mat]:
... print repr(mat), mat.groups(), mat.group()
... elif 4==5: 'haw'
... else:
... print 'final else'
...
final else
final else
final else
<_sre.SRE_Match object at 0x007F1260> () def
<_sre.SRE_Match object at 0x007F5900> () ghi

Hack #2: (attach temporary value to an instance of something
that can accept attributes (almost any object):

>>> import re
>>> pat = re.compile(r'...')
>>> mylist = ' a bc def ghij'.split(' ')
>>> mylist

['', 'a', 'bc', 'def', 'ghij']
>>> obj = type('Any',(),{})()
>>> for line in mylist:

... if 1==2: 'naw'
... elif 3==4: 'neither'
... elif setattr(obj,'mat', pat.search(line)) or obj.mat:
... print repr(obj.mat), obj.mat.groups(), obj.mat.group()
... elif 4==5: 'haw'
... else:
... print 'final else'
...
final else
final else
final else
<_sre.SRE_Match object at 0x007F69C0> () def
<_sre.SRE_Match object at 0x007F6980> () ghi

The trick above is that setattr(...) return None, so the expression always continues to the or part.
>>> setattr(obj,'xxx',123)
>>> repr(setattr(obj,'xxx',123))

'None'

You can spell

... elif setattr(obj,'mat', pat.search(line)) or obj.mat:
... print repr(obj.mat), obj.mat.groups(), obj.mat.group()

a little slicker if you make a special object to hold a binding to
the pat.search result, e.g., h is the Holder instance in the following,
which remembers the last thing passed to it and immediately returns it,
and also returns that last thing on being called without an arg:

>>> mylist

['', 'a', 'bc', 'def', 'ghij']
>>> h = Holder()
>>> for line in mylist:

... if 1==2: 'naw'
... elif 3==4: 'neither'
... elif h(pat.search(line)):
... print repr(h()), h().groups(), h().group()
... elif 4==5: 'haw'
... else:
... print 'final else'
...
final else
final else
final else
<_sre.SRE_Match object at 0x007F6FC0> () def
<_sre.SRE_Match object at 0x007F6F80> () ghi

Obviously
... print repr(h()), h().groups(), h().group()
could have been
... mat=h(); print repr(mat), mat.groups(), mat.group()
instead.

E.g., using the leftover value in h:

>>> print repr(h()), h().groups(), h().group()

<_sre.SRE_Match object at 0x007F6F80> () ghi
>>> mat=h(); print repr(mat), mat.groups(), mat.group()

<_sre.SRE_Match object at 0x007F6F80> () ghi


>Of course I can do this:
>
>for line in mylist:
> mat = pat.search(line)
> if ...:
> ....
> elif ...:
> ....
> elif mat:
> ...
>but the test is relevant in only a relatively small number of cases.
>And i would like to know if there exists a general solution
>for this kind of problem.


Take a pick, but not the list comprehension

Regards,
Bengt Richter
 
Reply With Quote
 
 
 
 
Bengt Richter
Guest
Posts: n/a
 
      07-25-2003
On 25 Jul 2003 02:17:24 GMT, (Bengt Richter) wrote:
[...]
>You can spell
>
> ... elif setattr(obj,'mat', pat.search(line)) or obj.mat:
> ... print repr(obj.mat), obj.mat.groups(), obj.mat.group()
>
>a little slicker if you make a special object to hold a binding to
>the pat.search result, e.g., h is the Holder instance in the following,
>which remembers the last thing passed to it and immediately returns it,
>and also returns that last thing on being called without an arg:
>
> >>> mylist

> ['', 'a', 'bc', 'def', 'ghij']
> >>> h = Holder()
> >>> for line in mylist:

> ... if 1==2: 'naw'
> ... elif 3==4: 'neither'
> ... elif h(pat.search(line)):
> ... print repr(h()), h().groups(), h().group()
> ... elif 4==5: 'haw'
> ... else:
> ... print 'final else'
> ...
> final else
> final else
> final else
> <_sre.SRE_Match object at 0x007F6FC0> () def
> <_sre.SRE_Match object at 0x007F6F80> () ghi
>
>Obviously
> ... print repr(h()), h().groups(), h().group()
>could have been
> ... mat=h(); print repr(mat), mat.groups(), mat.group()
>instead.
>

Sorry, I seem to have snipped out a Holder definition, in case anyone cares:

>>> class Holder(object):

... def __call__(self, *args):
... if args: self.val = args[0]
... return self.val
...
>>> h = Holder()
>>> h(123)

123
>>> h()

123
>>> h(345),h(),h(67,h() # result depends on left-to-right eval here

(345, 345, 678, 67

Regards,
Bengt Richter
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
new RegExp().test() or just RegExp().test() Matěj Cepl Javascript 3 11-24-2009 02:41 PM
[regexp] How to convert string "/regexp/i" to /regexp/i - ? Joao Silva Ruby 16 08-21-2009 05:52 PM
UK Only: Cost of Test? Thomson Prometric Want GBP105.00 Per Test! W A+ Certification 1 05-29-2006 05:14 PM
twice(twice(x)) Kiuhnm C++ 2 04-01-2006 04:41 PM
test test test test test test test Computer Support 2 07-02-2003 06:02 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57