Why doesn't ignorecase flag (re.I) work in re.sub() [duplicate]

Seems to me that you should be doing:

import re
print(re.sub('class', 'function', 'Class object', flags=re.I))

Without this, the re.I argument is passed to the count argument.


The flags argument is the fifth one - you're passing the value of re.I as the count argument (an easy mistake to make).


Note for those who still deal with Python 2.6.x installations or older. Python documentation for 2.6 re says:

re.sub(pattern, repl, string[, count])

re.compile(pattern[, flags])

This means you cannot pass flags directly to sub. They can only be used with compile:

regex = re.compile('class', re.I)
regex.sub("function", "Class object")

To avoid mistakes of this kind, the following monkey patching can be used:

import re
re.sub = lambda pattern, repl, string, *, count=0, flags=0, _fun=re.sub: \
    _fun(pattern, repl, string, count=count, flags=flags)

(* is to forbid specifying count, flags as positional arguments. _fun=re.sub is to use the declaration-time re.sub.)

Demo:

$ python
Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.sub(r'\b or \b', ',', 'or x', re.X)
'or x'   # ?!
>>> re.sub = lambda pattern, repl, string, *, count=0, flags=0, _fun=re.sub: \
...     _fun(pattern, repl, string, count=count, flags=flags)
>>> re.sub(r'\b or \b', ',', 'or x', re.X)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes 3 positional arguments but 4 were given
>>> re.sub(r'\b or \b', ',', 'or x', flags=re.X)
', x'
>>>