Skip to content

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.

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.

PatternMeaningExample
^ 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.

PatternMeaningExample
* 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

PatternMeaningExample
. 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

PatternMeaningExample
(...) 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.

PatternMeaningExample
(?=...) 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.

FlagMeaningNotes
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.

PatternMeaning
\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:

PatternMatches
athe literal character a
.one UTF-16 code unit except line terminators; Unicode mode matches a code point; s includes line terminators
\dany digit (0-9)
\Dany non-digit
\wa word character ([A-Za-z0-9_])
\Wa non-word character
\sa whitespace character (space, tab, newline)
\Sa 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:

PatternMatches
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:

PatternMatches
^start of string (or start of line with m flag)
$end of string (or end of line with m flag)
\bword boundary
\Bnot 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):

FlagEffect
gglobal — find all matches, not just first
icase-insensitive
mmultiline — ^ and $ match line boundaries
sdotall — . matches newlines
uUnicode — proper code-point handling, \p{} works
vUnicode sets and additional property features; use instead of u, not with it
ysticky — match must start at lastIndex
dindices — 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:

FeatureJavaScriptPythonPerl/PCREGo (RE2)
LookbehindES2018+yesyesno
Backreferencesyesyesyesno
Named groups(?<name>...)(?P<name>...)(?<name>...) or (?P<name>...)(?P<name>...)
Recursive patternsnonoyesno
Conditional patternsnoyesyesno
Possessive quantifiers (a*+)noyes, Python 3.11+yesno
Unicode property escapes\p{L} with u or vno \p{} in standard reyesyes, 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 g flag. Without it, only the first match is found. JavaScript’s replace only replaces the first match without g.
  • Greedy vs lazy. <.*> matches from the first < to the last >. Use <.*?> or <[^>]*>.
  • . not matching newlines without s flag. A pattern that “should match anything” doesn’t match across lines without s.
  • Unicode without u flag. Without u, surrogate pairs (most emoji) are two characters. With u, code points are atomic and \p{} Unicode properties work.
  • Locale-specific case rules. JavaScript i is not locale-sensitive. Unicode-aware case folding with u or v differs from legacy mode; for example /[a-z]/iu matches the Kelvin sign K. 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.