Regex Cheat Sheet
Regex syntax reference — anchors, quantifiers, character classes, groups, lookarounds, backreferences, and flags. With practical examples.
A practical regex reference: pattern, what it matches, and a real example for each construct.
No matches.
This reference primarily uses JavaScript syntax. Engine and version differences matter; Python or Perl examples are labeled separately. Test patterns interactively in the Regex Tester.
Anchors
Match positions, not characters.
| Pattern | Meaning | Example |
|---|---|---|
^ | Start of string (or start of line with /m flag) | ^Hello matches "Hello" only when at start |
$ | End of string (or end of line with /m flag) | end$ matches "end" only at end |
\b | Word boundary | \bcat\b matches "cat" but not "cats" or "catfish" |
\B | Non-word boundary | \Bcat matches "cat" in "scatter" but not "cat" alone |
\A | Absolute start (Python / Perl example; check runtime support elsewhere) | Like ^ but ignores /m flag |
\Z | End assertion (Python / Perl example; final-newline behavior varies) | Like $ but ignores /m flag |
Quantifiers
How many times to match the preceding element. Greedy by default; add <code>?</code> to make lazy.
| Pattern | Meaning | Example |
|---|---|---|
* | 0 or more (greedy) | a* matches "", "a", "aa", "aaa"… |
+ | 1 or more (greedy) | a+ matches "a", "aa", "aaa"… |
? | 0 or 1 (optional) | colou?r matches "color" or "colour" |
{n} | Exactly n times | \d{4} matches exactly 4 digits |
{n,} | At least n times | a{2,} matches 2 or more "a"s |
{n,m} | Between n and m times | \d{2,4} matches 2 to 4 digits |
*? | 0 or more (lazy) | <.*?> matches one tag, not everything between < and last > |
+? | 1 or more (lazy) | Stops at the first match |
?? | 0 or 1 (lazy) | Prefers no match if possible |
Character Classes
| Pattern | Meaning | Example |
|---|---|---|
. | One code unit (code point with u/v), except line terminators unless s is set | a.c matches "abc", "a c", "a1c" |
\d | Digit (equivalent to [0-9]) | \d+ matches one or more digits |
\D | Non-digit | Anything that isn't 0-9 |
\w | Word character (letter, digit, or underscore) | Usually [A-Za-z0-9_]; Unicode-aware i can add case-fold equivalents |
\W | Non-word character | Punctuation, whitespace, etc. |
\s | Whitespace (space, tab, newline, etc.) | \s+ matches one or more whitespace chars |
\S | Non-whitespace | Anything outside the engine whitespace class |
[abc] | Any character in the set | [aeiou] matches any vowel |
[^abc] | Any character NOT in the set | [^0-9] matches any non-digit |
[a-z] | Range | [a-zA-Z] matches an ASCII letter |
\. | Escaped literal — matches a period | Backslash escapes any special metacharacter |
Groups & Alternation
| Pattern | Meaning | Example |
|---|---|---|
(...) | Capturing group | (\d{4})-(\d{2}) captures year and month separately |
(?:...) | Non-capturing group | (?:foo|bar) alternation without capturing |
(?<name>...) | Named capturing group (Python re: (?P<name>...)) | (?<year>\d{4}) replacement string: $<year>; match result: groups.year |
| | Alternation (OR) | cat|dog|fish matches any of the three |
\1, \2… | Backreference to nth capturing group | (\w+) \1 matches doubled words |
\k<name> | Backreference to named group (Python re: (?P=name)) | Refer to (?<name>...) elsewhere in the pattern |
Lookarounds
Match a position based on what comes before/after, without consuming characters.
| Pattern | Meaning | Example |
|---|---|---|
(?=...) | Positive lookahead | \d(?=px) matches a digit followed by "px" (without consuming "px") |
(?!...) | Negative lookahead | \d(?!px) matches a digit NOT followed by "px" |
(?<=...) | Positive lookbehind | (?<=\$)\d+ matches digits preceded by "$" |
(?<!...) | Negative lookbehind | (?<!\\)" matches a quote not preceded by a backslash |
Flags
Modifiers that change how the pattern is interpreted. Syntax varies by language; <code>/pattern/flags</code> is JavaScript / Perl.
| Flag | Meaning | Notes |
|---|---|---|
g | Global — find all matches, not just the first | Required when passing a RegExp to String.replaceAll |
i | Case-insensitive | /hello/i matches "Hello", "HELLO" |
m | Multiline — ^ and $ match per-line, not per-string | |
s | Dotall — . matches newlines too | |
u | Unicode mode (JS) — enables \p{...} and treats surrogate pairs as one char | |
v | Unicode sets (JS) — use instead of u | Adds set operations and Unicode string properties |
d | Match indices (JS) | Adds start/end indices to match results |
y | Sticky (JS) — match must start at lastIndex | |
x | Extended — ignore whitespace + allow comments inside the pattern (Perl, Python; not JS) |
Special Characters
Metacharacters that need escaping (with <code>\</code>) when matched literally.
| Pattern | Meaning |
|---|---|
\n | Newline (LF) |
\r | Carriage return (CR) |
\t | Tab |
\v | Vertical tab |
\f | Form feed |
\0 | Null character |
\xFF | Hex character (FF = 255) |
\uFFFF | 4-digit Unicode character |
\u{1F600} | Variable-width Unicode (with /u flag) |
Special metacharacters: . ^ $ * + ? ( ) [ ] { } | \ | Escape any of these to match literally |
A regex (regular expression) is a small language for matching patterns in text. The reference page above is the cheat sheet; this companion explains the structure and where the dialects diverge.
The atoms
What you can match in one position:
| Pattern | Matches |
|---|---|
a | the literal character a |
. | one UTF-16 code unit except line terminators; Unicode mode matches a code point; s includes line terminators |
\d | any digit (0-9) |
\D | any non-digit |
\w | a word character ([A-Za-z0-9_]) |
\W | a non-word character |
\s | a whitespace character (space, tab, newline) |
\S | a non-whitespace character |
[abc] | one of a, b, c |
[^abc] | any character except a, b, c |
[a-z] | any character in the range a–z |
\p{Letter} | a Unicode letter (with u flag) |
These single-character examples consume a code unit by default or a code point with u. In v mode, some Unicode properties can match strings. A code point is not necessarily a whole visible symbol.
The quantifiers
How many times an atom must repeat:
| Pattern | Matches |
|---|---|
a* | zero or more a |
a+ | one or more a |
a? | zero or one a |
a{3} | exactly 3 a |
a{3,} | 3 or more a |
a{3,5} | 3 to 5 a |
Add ? after a quantifier for lazy matching (match as few as possible):
".*" matches: "the entire span between first and last quote"
".*?" matches: the first quoted span; use g to find subsequent spans
Anchors
Match positions, not characters:
| Pattern | Matches |
|---|---|
^ | start of string (or start of line with m flag) |
$ | end of string (or end of line with m flag) |
\b | word boundary |
\B | not a word boundary |
(?=foo) | lookahead — followed by foo (without consuming) |
(?!foo) | negative lookahead |
(?<=foo) | lookbehind — preceded by foo |
(?<!foo) | negative lookbehind |
Lookarounds are zero-width — they assert a condition without consuming characters.
Groups
(abc) ← capturing group; result[1], or $1 in a replacement string
(?:abc) ← non-capturing group
(?<name>abc) ← named group; result.groups.name, or $<name> in a replacement string
\1 ← backreference to first group
\k<name> ← backreference to named group
Capturing groups make extraction possible. Non-capturing groups ((?:...)) are for grouping precedence without keeping the match around when you do not need the captured value.
Alternation
cat|dog ← matches "cat" or "dog"
^(cat|dog)$ ← parens needed because alternation has low precedence
| has the lowest precedence in regex. cat|dog$ means “cat” or “dog at end of string”; (cat|dog)$ means “cat or dog at end.”
Flags
JavaScript regex flags (other engines differ):
| Flag | Effect |
|---|---|
g | global — find all matches, not just first |
i | case-insensitive |
m | multiline — ^ and $ match line boundaries |
s | dotall — . matches newlines |
u | Unicode — proper code-point handling, \p{} works |
v | Unicode sets and additional property features; use instead of u, not with it |
y | sticky — match must start at lastIndex |
d | indices — return start/end of each match |
Flags appear after the closing slash in literal regex: /foo/gi. In RegExp constructor: new RegExp('foo', 'gi').
Engine differences
Similar-looking syntax does not guarantee the same behavior. In particular, Python string patterns use Unicode-aware \w and \d by default, unlike JavaScript. Check the runtime and version:
| Feature | JavaScript | Python | Perl/PCRE | Go (RE2) |
|---|---|---|---|---|
| Lookbehind | ES2018+ | yes | yes | no |
| Backreferences | yes | yes | yes | no |
| Named groups | (?<name>...) | (?P<name>...) | (?<name>...) or (?P<name>...) | (?P<name>...) |
| Recursive patterns | no | no | yes | no |
| Conditional patterns | no | yes | yes | no |
Possessive quantifiers (a*+) | no | yes, Python 3.11+ | yes | no |
| Unicode property escapes | \p{L} with u or v | no \p{} in standard re | yes | yes, e.g. \p{L} or \p{Greek} |
Go uses RE2-style syntax without backreferences or lookaround. Its regular-expression implementation guarantees matching time linear in input size. Do not confuse Python’s standard re module with the separate third-party regex package.
Catastrophic backtracking
Some patterns are slow against certain inputs:
Pattern: (a+)+$
Input: aaaaaaaaaaaaaaaaaab
A backtracking engine can explore exponentially many partitions of the a run before rejecting the final b. Runtime optimizations differ; do not assume every engine or version takes the same time.
Symptoms: a regex that’s instant for short input but locks up the page (or process) for long input. Detection: pattern with nested quantifiers over the same character class. Cure: rewrite to avoid the ambiguity, or use an engine with a suitable time guarantee. RE2 accepts (a+)+$ and evaluates it without exponential backtracking; it rejects unsupported features such as backreferences, not all nested quantifiers.
Escaping
To match a literal special character, prefix with \:
\. literal dot
\( literal open paren
\\ literal backslash
\/ literal forward slash (in JS regex literals)
The set of characters needing escape in regex: . * + ? ^ $ ( ) [ ] { } | \. Character classes have different rules: a hyphen can define a range, and v mode adds reserved punctuation. Escape for the actual context; do not reuse a home-made outside-class escape list inside a class.
Common pitfalls
- Forgetting
gflag. Without it, only the first match is found. JavaScript’sreplaceonly replaces the first match withoutg. - Greedy vs lazy.
<.*>matches from the first<to the last>. Use<.*?>or<[^>]*>. .not matching newlines withoutsflag. A pattern that “should match anything” doesn’t match across lines withouts.- Unicode without
uflag. Withoutu, surrogate pairs (most emoji) are two characters. Withu, code points are atomic and\p{}Unicode properties work. - Locale-specific case rules. JavaScript
iis not locale-sensitive. Unicode-aware case folding withuorvdiffers from legacy mode; for example/[a-z]/iumatches the Kelvin signK. It is not a Turkish-language collation API. - Confusing regex flavors. A pattern that works in Python may not work in JavaScript. Test in the actual engine.
For interactive testing, see regex tester.
Sources and scope
Checked September 27, 2026: MDN syntax, Unicode sets, Python re, Go syntax, and RE2 syntax. Test a pattern in the engine that will run it.