I need to find all matches in a string for a given regex. I’ve been using findall() to do that until I came across a case where it wasn’t doing what I expected. For example:
regex = re.compile('(\d+,?)+')
s = 'There are 9,000,000 bicycles in Beijing.'
print re.search(regex, s).group(0)
> 9,000,000
print re.findall(regex, s)
> ['000']
In this case search() returns what I need (the longest match) but findall() behaves differently, although the docs imply it should be the same:
findall()matches all occurrences of a pattern, not just the first one
assearch()does.
-
Why is the behaviour different?
-
How can I achieve the result of
search()withfindall()(or something else)?
Ok, I see what’s going on… from the docs:
As it turns out, you do have a group, “(\d+,?)”… so, what it’s returning is the last occurrence of this group, or 000.
One solution is to surround the entire regex by a group, like this
then, it will return [(‘9,000,000’, ‘000’)], which is a tuple containing both matched groups. of course, you only care about the first one.
Personally, i would use the following regex
to avoid matching stuff like ” this is a bad number 9,123,”
Edit.
Here’s a way to avoid having to surround the expression by parenthesis or deal with tuples
finditer returns an iterator that you can use to access all the matches found. these match objects are the same that re.search returns, so group(0) returns the result you expect.