61

I would like to use more than one flag with the re.findall function. More specifically, I would like to use the IGNORECASE and DOTALL flags at the same time.

x = re.findall(r'CAT.+?END', 'Cat \n eND', (re.I, re.DOTALL))

Error :

Traceback (most recent call last):
  File "<pyshell#78>", line 1, in <module>
    x = re.findall(r'CAT.+?END','Cat \n eND',(re.I,re.DOTALL))
  File "C:\Python27\lib\re.py", line 177, in findall
    return _compile(pattern, flags).findall(string)
  File "C:\Python27\lib\re.py", line 243, in _compile
    p = sre_compile.compile(pattern, flags)
  File "C:\Python27\lib\sre_compile.py", line 500, in compile
    p = sre_parse.parse(p, flags)
  File "C:\Python27\lib\sre_parse.py", line 673, in parse
    p = _parse_sub(source, pattern, 0)
  File "C:\Python27\lib\sre_parse.py", line 308, in _parse_sub
    itemsappend(_parse(source, state))
  File "C:\Python27\lib\sre_parse.py", line 401, in _parse
    if state.flags & SRE_FLAG_VERBOSE:
TypeError: unsupported operand type(s) for &: 'tuple' and 'int'

Is there a way to use more than one flag ?

AMC
  • 2,642
  • 7
  • 13
  • 35
Pavan
  • 2,715
  • 4
  • 18
  • 19
  • 3
    See the documentation for [re.compile](https://docs.python.org/2/library/re.html#re.compile). – Peter Wood Jun 04 '15 at 18:27
  • 3
    In addition to @PeterWood's link: https://docs.python.org/2.7/howto/regex.html#compilation-flags – fenceop Jun 04 '15 at 18:28
  • 2
    If you use a lot of regex, its always better to use in-line modifiers if you can. Mostly because you are not actually using _`FLAGS`_ with the FindAll function, they are being passed to and attached to the Regular Expression object. The modifiers bind to the regex object, not the regex usage functions. So, if you cut and paste a regex somewhere else, you don't have to worry about flags at all. So, `r'(?si)CAT.+?END'` is the best way. –  Jun 04 '15 at 19:14
  • @PeterWood, the documentation for 3.8.1 is useless for this question. – Zach Young Nov 21 '20 at 09:10
  • @ZachYoung I answered the question 5 1/2 years ago. – Peter Wood Nov 21 '20 at 11:49

3 Answers3

129

Yes, but you have to OR them together:

x = re.findall(pattern=r'CAT.+?END', string='Cat \n eND', flags=re.I | re.DOTALL)
AMC
  • 2,642
  • 7
  • 13
  • 35
mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 3
    I always encourage everybody to use `flags=` when passing flags. If you don't, `my_regex.search` and `my_regex.match` will interpret the flags (which are `int`s internally) as the `pos` argument. So you'll mean to be doing `my_regex.search(my_str, re.DOTALL)`, but that'll be interpreted as `my_regex.search(my_str, pos=16)`. If you always use `flags=`, you'll get an error in the above, and you'll properly use `re.search` instead. – mlissner Jun 08 '20 at 17:26
  • 1
    In the official docs is the 2nd sentence under – run_the_race Nov 16 '21 at 16:50
  • Hi AMC and @mipadi, why is OR necessary? What is the difference if I use AND instead? – Valerio Ficcadenti Jul 18 '23 at 05:08
  • @ValerioFiccadenti: They are [bit masks](https://stackoverflow.com/a/10493604/28804) so if you AND them together you will not end up with the right value. – mipadi Jul 18 '23 at 23:54
19

You can't put the flags within a tuple. Use the pipe character (OR operand) within your flags:

x = re.findall(r'CAT.+?END','Cat \n eND',flags=re.I | re.DOTALL)
Serxalles
  • 3
  • 3
Mazdak
  • 105,000
  • 18
  • 159
  • 188
17

Is there a way to use more than one flag ?

It wasn't mentioned, but you can use inline (?...) modifiers as well.

x = re.findall(r'(?si)CAT.+?END', 'Cat \n eND')
hwnd
  • 69,796
  • 4
  • 95
  • 132