Help with regular expression in python

Carl Banks pavlovevidence at gmail.com
Fri Aug 19 22:11:58 CEST 2011


On Friday, August 19, 2011 10:33:49 AM UTC-7, Matt Funk wrote:
> number = r"\d\.\d+e\+\d+"
> numbersequence = r"%s( %s){31}(.+)" % (number,number)
> instance_linetype_pattern = re.compile(numbersequence)
> 
> The results obtained are:
> results: 
> [(' 2.199000e+01', ' : (instance: 0)\t:\tsome description')]
> so this matches the last number plus the string at the end of the line, but no 
> retaining the previous numbers.
> 
> Anyway, i think at this point i will go another route. Not sure where the 
> issues lies at this point.


I think the problem is that repeat counts don't actually repeat the groupings; they just repeat the matchings.  Take this expression:

r"(\w+\s*){2}"

This will match exactly two words separated by whitespace.  But the match result won't contain two groups; it'll only contain one group, and the value of that group will match only the very last thing repeated:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> m = re.match(r"(\w+\s*){2}","abc def")
>>> m.group(1)
'def'

So you see, the regular expression is doing what you think it is, but the way it forms groups is not.


Just a little advice (I know you've found a different method, and that's good, this is for the general reader).

The functions re.findall and re.finditer could have helped here, they find all the matches in a string and let you iterate through them.  (findall returns the strings matched, and finditer returns the sequence of match objects.)  You could have done something like this:

row = [ float(x) for x in re.findall(r'\d+\.\d+e\+d+',line) ]

And regexp matching is often overkill for a particular problem; this may be of them.  line.split() could have been sufficient:

row = [ float(x) for x in line.split() ]

Of course, these solutions don't account for the case where you have lines, some of which aren't 32 floating-point numbers.  You need extra error handling for that, but you get the idea.


Carl Banks



More information about the Python-list mailing list