Regex Cheat Sheet for Developers — Patterns, Examples & Common Mistakes
Regular expressions are one of those things you learn just enough of, use once, and then forget immediately. This is the reference you'll actually bookmark — every metacharacter, the patterns you'll copy most often, and the mistakes that waste hours of debugging.
Metacharacters
| Pattern | Matches | Example |
|---|---|---|
. | Any character except newline | a.c → abc, a1c, a-c |
\d | Any digit (0-9) | \d{3} → 123, 456 |
\D | Any non-digit | \D+ → abc, --- |
\w | Word character (letter, digit, underscore) | \w+ → hello, var_1 |
\W | Non-word character | \W → @, #, space |
\s | Whitespace (space, tab, newline) | \s+ → " ", "\t" |
\S | Non-whitespace | \S+ → hello |
\b | Word boundary | \bcat\b → "cat" but not "scatter" |
Quantifiers
| Pattern | Meaning | Example |
|---|---|---|
* | 0 or more (greedy) | a* → "", a, aaa |
+ | 1 or more (greedy) | a+ → a, aaa (not "") |
? | 0 or 1 (optional) | colou?r → color, colour |
{n} | Exactly n times | \d{4} → 2026 |
{n,} | n or more times | \d{2,} → 12, 123, 1234 |
{n,m} | Between n and m times | \d{2,4} → 12, 123, 1234 |
*? | 0 or more (lazy) | Matches as few as possible |
+? | 1 or more (lazy) | Matches as few as possible |
Anchors and Boundaries
| Pattern | Meaning |
|---|---|
^ | Start of string (or line with m flag) |
$ | End of string (or line with m flag) |
\b | Word boundary — between \w and \W |
\B | Not a word boundary |
Key distinction: ^abc matches "abc" only at the start of a string. abc without the anchor matches "abc" anywhere in the string.
Character Classes
| Pattern | Matches |
|---|---|
[abc] | Any one of a, b, or c |
[a-z] | Any lowercase letter |
[A-Z] | Any uppercase letter |
[0-9] | Any digit (same as \d) |
[a-zA-Z0-9] | Any alphanumeric character |
[^abc] | Any character EXCEPT a, b, or c |
Inside [], most special characters lose their meaning. A literal hyphen goes first or last: [-a-z] or [a-z-]. A literal ] goes first: []a-z].
Groups and Alternation
| Pattern | Meaning |
|---|---|
(abc) | Capturing group — captures "abc" |
(?:abc) | Non-capturing group — groups without capturing |
a|b | Alternation — matches a OR b |
\1 | Backreference — matches same text as group 1 |
(?<name>abc) | Named group — captured as "name" |
# Extract date parts with named groups
(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
Input: 2026-06-15
Groups: year=2026, month=06, day=15
Greedy vs Lazy Matching
This is the #1 source of unexpected regex behavior:
Input: <b>hello</b> world <b>foo</b>
Greedy: <b>.*</b> → "<b>hello</b> world <b>foo</b>" (entire string!)
Lazy: <b>.*?</b> → "<b>hello</b>" (first match only)
Greedy (.*) matches as much as possible. Lazy (.*?) matches as little as possible. When you want the shortest match, always use the lazy version.
Lookahead and Lookbehind
| Pattern | Meaning | Example |
|---|---|---|
(?=abc) | Positive lookahead — followed by "abc" | \d+(?= USD) → "100" in "100 USD" |
(?!abc) | Negative lookahead — NOT followed by "abc" | \d+(?! USD) → "200" in "200 EUR" |
(?<=abc) | Positive lookbehind — preceded by "abc" | (?<=\$)\d+ → "50" in "$50" |
(?<!abc) | Negative lookbehind — NOT preceded by "abc" | (?<!\$)\d+ → "50" in "€50" |
Lookarounds assert a condition without consuming characters — the matched text does not include the lookaround part.
Patterns You'll Copy the Most
| What | Pattern |
|---|---|
| Date (YYYY-MM-DD) | \d{4}-\d{2}-\d{2} |
| Email (basic) | [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} |
| URL (http/https) | https?://[^\s]+ |
| IPv4 address | \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b |
| Phone (US) | \(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4} |
| Hex color | #[0-9a-fA-F]{3,8} |
| HTML tag | <[^>]+> |
| Blank lines | ^\s*$ (with m flag) |
| Trailing whitespace | \s+$ (with m flag) |
| Quoted string | "[^"]*" or '[^']*' |
Important: the email regex above is a practical approximation, not RFC 5322 compliant. For production email validation, use your language's built-in validator or a library — regex alone cannot fully validate email addresses.
Regex Flags
| Flag | Name | Effect |
|---|---|---|
g | Global | Find all matches, not just the first |
i | Case-insensitive | /abc/i matches ABC, Abc, etc. |
m | Multiline | ^ and $ match line boundaries, not just string boundaries |
s | Dotall | . matches newline characters too |
Common Mistakes
- Not escaping the dot —
.matches any character. To match a literal period, use\.. The patternexample.comalso matches "exampleXcom." - Greedy matching surprises —
.*grabs as much as it can. If you're extracting content between delimiters (like HTML tags), use.*?(lazy) or[^<]*(negated class). - Catastrophic backtracking — patterns like
(a+)+can take exponential time on certain inputs. Avoid nested quantifiers on overlapping patterns. - Using regex for HTML parsing — regex cannot handle nested structures. Use a proper HTML parser (DOMParser in JS, BeautifulSoup in Python) for anything beyond simple tag matching.
- Forgetting anchors — without
^and$, your validation pattern matches substrings.\d{3}matches "123" inside "abc123xyz." Use^\d{3}$for exact match. - Locale and Unicode issues —
\wonly matches ASCII word characters in most engines. For Unicode letters, use Unicode property escapes:\p{L}(JavaScript withuflag).
Frequently Asked Questions
Which regex flavor should I learn?
PCRE (Perl Compatible Regular Expressions) is the most widely used flavor. JavaScript, Python, Java and Go all use PCRE-like syntax with minor differences. Learn PCRE and you're covered for 95% of use cases.
How do I debug a complex regex?
Break it into parts and test each group separately. Use our Regex Tester to see matches highlighted in real time. For complex patterns, add comments using the x (verbose) flag.
Is there a performance cost to capturing groups?
Yes, capturing groups allocate memory to store the matched text. Use non-capturing groups (?:...) when you don't need the captured value. In performance-critical code, this matters.
Can regex match balanced brackets or nested structures?
Standard regex cannot. Some flavors (PCRE, .NET) support recursive patterns, but it's better to use a parser for nested structures like HTML, JSON or programming languages.
Paste a regex and test text to see matches highlighted in real time. Supports flags, groups, and substitution. Runs 100% in your browser.
Regex Tester → Regex Generator →