Regex flags global case-insensitive multiline explained
g flag, i flag, m flag, s flag, flag combinations, findAll behavior, flag syntax JS vs Python
Flags Change How the Engine Behaves
Flags are appended after the closing delimiter in JavaScript (/pattern/flags) or passed as a string argument in Python (re.findall(pattern, string, re.I)). They modify engine behavior globally for that pattern.
The Four You'll Actually Use
iโ case-insensitive:amatchesAgโ global: find all matches, not just the firstmโ multiline:^/$match line boundariessโ dotAll: dot matches newlines too
// JavaScript
'Hello WORLD'.match(/hello/i) // ['Hello']
'aabbcc'.match(/[a-z]/g) // ['a','a','b','b','c','c']
'line1\nline2'.match(/^line\d/gm) // ['line1', 'line2']
# Python
re.findall(r'hello', 'Hello WORLD', re.I) # ['Hello']
re.findall(r'[a-z]', 'aabbcc') # ['a','a','b','b','c','c']
re.findall(r'^line\d', 'line1\nline2', re.M) # ['line1', 'line2']
Combine Flags
/pattern/gi // global + case-insensitive
re.findall(r'pat', s, re.I | re.M) // Python combines with |
Without g, match() returns only the first result even if multiple exist. This is a common source of bugs โ always ask whether you want one match or all matches before choosing your method.
A subtle bug with the g flag: when you use regex.test(str) in a loop with a globally-flagged regex stored in a variable, the engine updates lastIndex after each call and starts from there next time. This causes alternating true/false results on repeated calls. The fix: either use a fresh regex literal each time, reset regex.lastIndex = 0 before testing, or use str.match(regex) which handles this correctly. This is one of the most common regex bugs in production JavaScript code.
