In many Python regex functions, you see a third argument flags. What are they and how do they work?
Flags allow you to control the regular expression engine. Because regular expressions are so powerful, they are a useful way of switching on and off certain features (e.g. whether to ignore capitalization when matching your regex).
For example, here’s how the third argument flags is used in the re.findall()
method:
re.findall(pattern, string, flags=0)
So the flags argument seems to be an integer argument with the default value of 0. To control the default regex behavior, you simply use one of the predefined integer values. You can access these predefined values via the re library:
Syntax | Meaning |
re.ASCII | If you donβt use this flag, the special Python regex symbols \w , \W , \b , \B , \d , \D , \s and \S will match Unicode characters. If you use this flag, those special symbols will match only ASCII characters β as the name suggests. |
re.A | Same as re.ASCII |
re.DEBUG | If you use this flag, Python will print some useful information to the shell that helps you debugging your regex. |
re.IGNORECASE | If you use this flag, the regex engine will perform case-insensitive matching. So, if you’re searching for character class [A-Z] , it will also match [a-z] . |
re.I | Same as re.IGNORECASE |
re.LOCALE | Don’t use this flag — ever. It’s depreciated—the idea was to perform case-insensitive matching depending on your current locale. But it isn’t reliable. |
re.L | Same as re.LOCALE |
re.MULTILINE | This flag switches on the following feature: the start-of-the-string regex '^' matches at the beginning of each line (rather than only at the beginning of the string). The same holds for the end-of-the-string regex '$' that now matches also at the end of each line in a multi-line string. |
re.M | Same as re.MULTILINE |
re.DOTALL | Without using this flag, the dot regex '.' matches all characters except the newline character '\n' . Switch on this flag to really match all characters including the newline character. |
re.S | Same as re.DOTALL |
re.VERBOSE | To improve the readability of complicated regular expressions, you may want to allow comments and (multi-line) formatting of the regex itself. This is possible with this flag: all whitespace characters and lines that start with the character '#' are ignored in the regex. |
re.X | Same as re.VERBOSE |
How to Use These Flags?
Simply include the flag as the optional flag
argument as follows:
import re text = ''' Ha! let me see her: out, alas! he's cold: Her blood is settled, and her joints are stiff; Life and these lips have long been separated: Death lies on her like an untimely frost Upon the sweetest flower of all the field. ''' print(re.findall('HER', text, flags=re.IGNORECASE)) # ['her', 'Her', 'her', 'her']
As you see, the re.IGNORECASE flag ensures that all occurrences of the string ‘her’ are matched—no matter their capitalization.
Related article: Python Regex Superpower – The Ultimate Guide
Do you want to master the regex superpower? Check out my new book The Smartest Way to Learn Regular Expressions in Python with the innovative 3-step approach for active learning: (1) study a book chapter, (2) solve a code puzzle, and (3) watch an educational chapter video.
How to Use Multiple Flags?
Yes, simply add them together (sum them up) as follows:
import re text = ''' Ha! let me see her: out, alas! he's cold: Her blood is settled, and her joints are stiff; Life and these lips have long been separated: Death lies on her like an untimely frost Upon the sweetest flower of all the field. ''' print(re.findall(' HER # Ignored', text, flags=re.IGNORECASE + re.VERBOSE)) # ['her', 'Her', 'her', 'her']
You use both flags re.IGNORECASE
(all occurrences of lower- or uppercase string variants of ‘her’ are matched) and re.VERBOSE
(ignore comments and whitespaces in the regex). You sum them together re.IGNORECASE + re.VERBOSE
to indicate that you want to take both.
Let’s dive into the different flags in more detail by example.
re.ASCII
If you don’t use this flag, the special Python regex symbols \w, \W, \b, \B, \d, \D, \s and \S will match Unicode characters. If you use this flag, those special symbols will match only ASCII characters — as the name suggests.
######################### # re.ASCII ######################### s = 'hello wΓΆrld' print(re.findall('\w+', s)) # ['hello', 'wΓΆrld'] print(re.findall('\w+', s, flags=re.ASCII)) # ['hello', 'w', 'rld']
re.DEBUG
If you use this flag, Python will print some useful information to the shell that helps you debugging your regex.
######################### # re.DEBUG ######################### s = 'hello world' print(re.findall('\w+', s, flags=re.DEBUG)) ''' MAX_REPEAT 1 MAXREPEAT IN CATEGORY CATEGORY_WORD 0. INFO 4 0b0 1 MAXREPEAT (to 5) 5: REPEAT_ONE 9 1 MAXREPEAT (to 15) 9. IN 4 (to 14) 11. CATEGORY UNI_WORD 13. FAILURE 14: SUCCESS 15: SUCCESS ['hello', 'world'] '''
re.IGNORECASE
If you use this flag, the regex engine will perform case-insensitive matching. So if you’re searching for [A-Z], it will also match [a-z].
######################### # re.IGNORECASE ########################## s = 'HELLO world' print(re.findall('[a-z]+', s)) # ['world'] print(re.findall('[a-z]+', s, flags=re.IGNORECASE)) # ['HELLO', 'world']
re.MULTILINE
This flag switches on the following feature: the start-of-the-string regex ‘^’ matches at the beginning of each line (rather than only at the beginning of the string). The same holds for the end-of-the-string regex ‘$’ that now matches also at the end of each line in a multi-line string.
######################### # re.MULTILINE ######################### s = '''hello world''' print(re.findall('^[a-z]+', s)) # ['hello'] print(re.findall('^[a-z]+', s, flags=re.MULTILINE)) # ['hello', 'world']
re.DOTALL
Without using this flag, the dot regex ‘.’ matches all characters except the newline character ‘\n’. Switch on this flag to really match all characters including the newline character.
######################### # re.DOTALL ######################### s = '''hello world''' print(re.findall('.+', s)) # ['hello', 'world'] print(re.findall('.*', s, flags=re.DOTALL)) # ['hello\nworld', '']
re.VERBOSE
To improve the readability of complicated regular expressions, you may want to allow comments and (multi-line) formatting of the regex itself. This is possible with this flag: all whitespace characters and lines that start with the character ‘#’ are ignored in the regex.
######################### # re.VERBOSE ######################### s = 'hello world' print(re.findall('.+ #I can now write comments', s, flags=re.VERBOSE)) # ['hello world']
Google, Facebook, and Amazon engineers are regular expression masters. If you want to become one as well, check out our new book: The Smartest Way to Learn Python Regex (Amazon Kindle/Print, opens in new tab).