Why using "re.I" flag in findall() function gives different results when function is used on the compiled regex object vs function used by itself

Viewed 354

I'm studying Python by myself and was not able to find explanation for this behavior:

When the regex object is first compiled and findall() method is used on the compiled regex object with re.I flag, the result is different than by using findall() function with the same flag by itself.

(Removing re.I flag from result variable "fixes" the dissimilarity of results.)

import re

emails1 = re.compile(r"([A-z0-9._+-]+@[A-z0-9._+-]+\.[A-z]{2,})")
result = emails1.findall("xxx@yyy.com", re.I)
print(result)
>>>['x@yyy.com']

emails2 = re.findall(r"([A-z0-9._+-]+@[A-z0-9._+-]+\.[A-z]{2,})", "xxx@yyy.com", re.I)
print(emails2)
>>>['xxx@yyy.com']

Appreciate any help or advice!

2 Answers

The findall method on a compiled regex has a different parameter signature than the findall function.

Function

findall(pattern, string, flags=0)

Method

findall(string, pos=0, endpos=9223372036854775807)

re.I is an enumeration with a value of 2, so you are really asking the compiled method to start at position 2, ignoring that first "xx".

In your first example, you're telling findall() to start at position 2 of the string. (re.I has the integer value 2.) So it skips the first two characters of the string.

If you look at the method signature of the findall() method you'll find that the second argument is pos, not flags. That's because you have to pass the flags at the time the regular expression is compiled, because they are baked in to the compiled regex object. You can't specify them later.

Related