Regex Cheat Sheet
Every regular expression construct in one filterable page — classes, quantifiers, groups, lookarounds and flags — plus copy-ready patterns and the backtracking traps to avoid.
Characters and classes
Character classes
| Pattern | Matches | Example |
|---|---|---|
| . | Any character except newline (unless the s flag is set) | a.c → abc, a1c |
| \d | Any digit, equivalent to [0-9] | \d\d → 42 |
| \D | Any non-digit | \D+ → abc |
| \w | Word character: letter, digit or underscore | \w+ → hello_1 |
| \W | Any non-word character | \W → space, comma |
| \s | Any whitespace: space, tab, newline | a\sb → 'a b' |
| \S | Any non-whitespace | \S+ → token |
| [abc] | Any one of a, b or c | [aeiou] → vowels |
| [^abc] | Any character except a, b or c | [^0-9] → non-digits |
| [a-z] | Range from a to z | [A-Za-z0-9] → alphanumeric |
| \p{L} | Any Unicode letter (needs the u flag) | \p{L}+ → café, 日本 |
| \p{Lu} | Any uppercase Unicode letter | \p{Lu} → A, É |
Anchors and boundaries
| Pattern | Matches | Example |
|---|---|---|
| ^ | Start of string, or of a line with the m flag | ^Hello |
| $ | End of string, or of a line with the m flag | world$ |
| \b | Word boundary | \bcat\b matches 'cat' not 'category' |
| \B | Not a word boundary | \Bcat matches 'bobcat' |
| \A | Absolute start of string (not in JavaScript) | |
| \z | Absolute end of string (not in JavaScript) |
Quantifiers and greediness
Quantifiers
| Pattern | Matches | Example |
|---|---|---|
| * | Zero or more | ab*c → ac, abc, abbc |
| + | One or more | ab+c → abc, abbc |
| ? | Zero or one, i.e. optional | colou?r → color, colour |
| {n} | Exactly n times | \d{4} → 2026 |
| {n,} | n or more times | \d{2,} → 42, 4242 |
| {n,m} | Between n and m times | \d{2,4} → 42, 424, 4242 |
| *? | Lazy zero or more | <.*?> matches one tag, not the whole line |
| +? | Lazy one or more | |
| ?? | Lazy optional |
Greedy versus lazy. By default quantifiers take as much as possible and then backtrack. Given <a><b>, the pattern <.*> matches the entire string, while <.*?> matches just <a>. The lazy form is usually what you want when extracting delimited content.
Groups, alternation and references
Grouping
| Pattern | Matches | Example |
|---|---|---|
| (abc) | Capturing group; also available as a back-reference | (\d+)-(\d+) |
| (?:abc) | Non-capturing group — groups without capturing | (?:ab)+ |
| (?<name>x) | Named capturing group | (?<year>\d{4}) |
| a|b | Alternation: a or b | cat|dog |
| \1 | Back-reference to group 1 | (\w)\1 matches doubled letters |
| \k<name> | Back-reference to a named group | |
| $1 | Group 1 in a replacement string | replace '$2 $1' |
Lookaround
| Pattern | Matches | Example |
|---|---|---|
| (?=x) | Positive lookahead: followed by x | \d+(?=px) → 24 in '24px' |
| (?!x) | Negative lookahead: not followed by x | \d+(?!px) |
| (?<=x) | Positive lookbehind: preceded by x | (?<=\$)\d+ → 30 in '$30' |
| (?<!x) | Negative lookbehind: not preceded by x |
Lookarounds are zero-width: they assert a condition without consuming characters, so they do not appear in the match. Lookbehind has been supported in all major browsers since 2023.
Flags
| Flag | Name | Effect |
|---|---|---|
g | Global | Find all matches, not just the first |
i | Ignore case | Case-insensitive matching |
m | Multiline | ^ and $ match at line breaks |
s | Dot all | . also matches newline |
u | Unicode | Enables \p{...} and correct astral handling |
y | Sticky | Match only from lastIndex |
d | Indices | Report start and end offsets of every group |
v | Unicode sets | Set operations inside character classes |
Patterns worth copying
| Goal | Pattern |
|---|---|
| Trim whitespace | ^\s+|\s+$ |
| Collapse repeated spaces | \s{2,} |
| ISO date | \d{4}-\d{2}-\d{2} |
| Hex colour | #(?:[0-9a-fA-F]{3}){1,2}\b |
| IPv4 octet | (?:25[0-5]|2[0-4]\d|1?\d?\d) |
| Email (pragmatic) | [^@\s]+@[^@\s]+\.[a-z]{2,} |
| URL | https?://[^\s"'<>]+ |
| HTML tag | </?[a-z][^>]*> |
| Duplicate word | \b(\w+)\s+\1\b |
| Leading zeros | ^0+(?=\d) |
| camelCase to kebab | ([a-z0-9])([A-Z]) → $1-$2 |
| Blank lines | ^\s*$\n? |
Do not parse HTML with regex. HTML is not a regular language: nesting, comments, CDATA and attribute quoting defeat any pattern you can write. Use DOMParser in the browser or a real parser server-side. The patterns above are for quick text scanning, not for building a parser.
Catastrophic backtracking
Some patterns take exponential time on inputs that fail to match. The classic shape is nested quantifiers over overlapping character sets:
(a+)+$ // catastrophic
(\w+\s?)*$ // catastrophic
(.*,)* // catastrophicGiven 30 letter a's followed by a b, (a+)+$ explores over a billion ways to split the input before concluding there is no match. This is ReDoS — regular expression denial of service — and it has taken down real services, including a Cloudflare outage in July 2019 and a well-documented Stack Overflow outage in 2016.
Defences:
- Avoid nesting a quantifier inside another quantified group.
- Make inner patterns mutually exclusive so there is only one way to match.
- Use possessive quantifiers or atomic groups where the engine supports them (JavaScript does not).
- Cap input length before matching.
- Never build a regex from unvalidated user input.
Test any pattern you plan to run on user input in the regex tester, which flags suspicious constructs.
Frequently Asked Questions
What is the difference between greedy and lazy quantifiers?
Greedy quantifiers match as much as possible and backtrack; lazy ones (with a trailing ?) match as little as possible. For extracting delimited content, lazy is usually correct.
What does \b mean in regex?
A word boundary — a zero-width position between a word character and a non-word character. \bcat\b matches “cat” but not “category”.
How do I match across multiple lines?
Use the s flag to let . match newlines, and the m flag to make ^ and $ match at line boundaries. They are independent.
Can I use regex to parse HTML?
No. HTML allows arbitrary nesting, which regular expressions cannot express. Use DOMParser or a proper parser; regex is fine only for quick scans of known-simple text.
What is catastrophic backtracking?
A pattern that takes exponential time on non-matching input, typically caused by nested quantifiers over overlapping sets. It is a denial-of-service risk when the input comes from users.
What is the difference between (abc) and (?:abc)?
Both group, but (?:...) does not capture. Use non-capturing groups when you only need grouping — it keeps back-references and replacement indices clean.
Does JavaScript support lookbehind?
Yes, in every major browser since 2023. (?<=\$)\d+ matches the digits after a dollar sign without including it.
Sources & further reading
- MDN: Regular expressions guide — the complete JavaScript regex reference
- ECMAScript specification — the normative grammar for JavaScript patterns
- OWASP: ReDoS — how catastrophic backtracking becomes a vulnerability
- Regular-Expressions.info — flavour-by-flavour comparison across languages