Flags fix the most common 'why doesn't it match across lines?' problems and make long patterns readable.
Flags (modifiers) change how a whole pattern behaves. The common ones exist in most flavours under similar letters:
iignore case. Python:re.IGNORECASE.mmultiline:^and$match at every line start and end, not just the string ends. Python:re.MULTILINE.sdotall:.also matches newline. Python:re.DOTALL.xverbose: whitespace in the pattern is ignored and#starts a comment, so complex patterns can be laid out over several lines. Python:re.VERBOSE; not available in JavaScript.
Flags can also be set inside the pattern: (?i)abc, or scoped to a group as (?i:abc). Python requires global inline flags at the very start of the pattern.
JavaScript adds flags of its own:
gglobal: needed formatchAlland forreplaceto change every match. It makes the regex object stateful throughlastIndex, which surprises people who reuse a/gregex withtest().ysticky: match only atlastIndex.uUnicode mode andv(ES2024) its stricter successor with set operations in classes.drecords start and end indices for groups.
Combine flags with | in Python (re.I | re.M) or by listing letters in JavaScript (/x/gimu).
Example
import re
text = "Title\nfirst line\nSecond line"
print(re.findall(r"^\w+", text)) # ['Title']
print(re.findall(r"^\w+", text, re.M)) # ['Title', 'first', 'Second']
print(re.findall(r"line$", text, re.M | re.I)) # ['line', 'line']
print(re.search(r"Title.*line", text)) # None: . stops at \n
print(re.search(r"Title.*line", text, re.S).group().count("\n")) # 2
phone = re.compile(r'''
\(?(\d{3})\)? # area code, optional parentheses
[\s.-]? # separator
(\d{3})[\s.-]?(\d{4})
''', re.VERBOSE)
print(phone.search("call (555) 123-4567").groups()) # ('555', '123', '4567')Remember
- i ignores case, m makes ^ $ per line, s lets . match newlines
- Verbose mode (x) allows whitespace and comments inside the pattern
- In JavaScript, g makes a regex stateful via lastIndex
Watch out for
- Reusing a /g regex with test() in JavaScript and getting alternating true/false because lastIndex moved.