Every regex flag in every language — full reference
Twelve distinct flags exist across major flavors. Most flavors have eight or nine. Here's exactly what each one does, with examples.
The summary table
| Flag | Meaning | JS | Python | PCRE |
|---|---|---|---|---|
i | Case insensitive | ✓ | ✓ (re.I) | ✓ |
g | Global — find all matches | ✓ | implicit (findall) | ✓ |
m | Multiline — ^ $ match line boundaries | ✓ | ✓ (re.M) | ✓ |
s | Dotall — . matches newlines | ✓ ES2018+ | ✓ (re.S) | ✓ |
u | Unicode-aware | ✓ ES2015+ | default in py3 | via (*UTF) |
x | Verbose — ignore whitespace, allow comments | ✗ | ✓ (re.X) | ✓ |
y | Sticky — match starts at lastIndex | ✓ | ✗ | via anchors |
d | Has match indices | ✓ ES2022+ | via match.span() | via PCRE2_AUTO_CALLOUT |
v | Set notation in character classes | ✓ ES2024+ | ✗ | ✗ |
i — case insensitive
/hello/i JavaScript
re.compile(r"hello", re.IGNORECASE) Python
Makes a match both a and A. With Unicode flags, full Unicode case folding applies (e.g., German ß matches SS).
g — global
"abc abc abc".match(/abc/g)
// ["abc", "abc", "abc"] — without /g, just the first
JavaScript-specific naming. Other languages have separate "find first" vs "find all" functions instead.
m — multiline
/^foo/m matches "foo" at the start of any line, not just the input
Changes the behavior of ^ and $. Doesn't affect . — that's a separate flag (s).
s — dotall
/a.b/s . now matches newlines too
Without it, . matches any character except newlines. Most "regex doesn't cross lines" problems are fixed by this flag.
u — Unicode-aware
/\d+/u treats Unicode digits as digits
/\p{Letter}/u Unicode property classes work
In JavaScript, also enables \u{...} code-point escapes and stricter syntax. In Python, on by default in py3 — set re.ASCII to opt out.
x — verbose / extended
Lets you write multi-line regex with comments:
re.compile(r"""
^(\d{4}) # year
-(\d{2}) # month
-(\d{2})$ # day
""", re.X)
Whitespace is ignored. # starts a comment. To match literal whitespace or #, escape them: \ , \#, or put them in character classes.
y — sticky (JavaScript only)
Like global, but each match must start exactly at lastIndex — no scanning ahead. Used for streaming parsers.
d — match indices (JS ES2022+)
Adds an indices property to match results with start/end positions for each capture group.
v — set notation (JS ES2024+)
Newest JS flag. Adds set operations inside character classes:
/[\p{Letter}--[aeiou]]/v letters except vowels (difference)
/[\p{Letter}&&\p{ASCII}]/v intersection
/[a-z||\d]/v union (same as a-z\d)
Combining flags
Stack them as one string:
JavaScript: /pattern/gim
Python: re.compile(r"...", re.I | re.M | re.X)
PCRE: /pattern/gims
Inline flag modifiers
Many flavors let you enable flags inline within the pattern:
(?i)abc rest of pattern case-insensitive
(?i:abc) only "abc" case-insensitive
(?i-s)abc enable i, disable s
(?ix) multiple flags
JavaScript supports inline flags as of recent versions, but for backwards compatibility most code uses the flag parameter instead.
The takeaway
The five flags you'll actually use most: i (case), g (global, JS), m (multiline), s (dotall), u (Unicode). The others handle specific niches — sticky parsing, verbose patterns, set notation — and most code never needs them.
When porting regex between flavors, check the flag spelling and combine syntax carefully. Most flavor differences are in capability, not in flag names — but Python uses constants while everyone else uses single letters.
Related reading
Try this pattern in the explainer
Paste any regex into the live explainer and see what each token means, with example matches in real time.
Open the regex explainer →