Regex Cheat Sheet
Complete regular expression reference. Character classes, quantifiers, anchors, groups, lookaheads, and ready-to-use patterns.
Characters
| Pattern | Description | Example |
|---|---|---|
. | Any character except newline | a.c matches abc, a1c |
\d | Digit (0-9) | \d{3} matches 123 |
\D | Non-digit | \D+ matches abc |
\w | Word character (a-z, A-Z, 0-9, _) | \w+ matches hello_1 |
\W | Non-word character | \W matches @, # |
\s | Whitespace (space, tab, newline) | \s+ matches spaces/tabs |
\S | Non-whitespace | \S+ matches hello |
\t | Tab character | |
\n | Newline character | |
\\ | Escaped backslash (literal \) | \\n matches literal \n |
Quantifiers
| Pattern | Description | Example |
|---|---|---|
* | 0 or more (greedy) | ab*c matches ac, abc, abbc |
+ | 1 or more (greedy) | ab+c matches abc, abbc (not ac) |
? | 0 or 1 (optional) | colou?r matches color, colour |
{n} | Exactly n times | \d{4} matches 2026 |
{n,} | n or more times | \d{2,} matches 12, 123, 1234 |
{n,m} | Between n and m times | \d{2,4} matches 12, 123, 1234 |
*? | 0 or more (lazy / non-greedy) | <.*?> matches first tag only |
+? | 1 or more (lazy) | ".+?" matches smallest quoted string |
?? | 0 or 1 (lazy) | Prefers 0 matches if possible |
Tip: Greedy quantifiers (
*, +) match as much as possible. Add ? to make them lazy (match as little as possible). This is crucial when parsing HTML tags or quoted strings.
Anchors & Boundaries
| Pattern | Description | Example |
|---|---|---|
^ | Start of string (or line with m flag) | ^Hello matches Hello world |
$ | End of string (or line with m flag) | world$ matches Hello world |
\b | Word boundary | \bcat\b matches cat but not catch |
\B | Non-word boundary | \Bcat\B matches concatenate |
Character Classes
| Pattern | Description | Example |
|---|---|---|
[abc] | Match a, b, or c | [aeiou] matches any vowel |
[^abc] | NOT a, b, or c | [^0-9] matches non-digits |
[a-z] | Range: a through z | [a-zA-Z] matches any letter |
[0-9] | Range: 0 through 9 | Same as \d |
[a-zA-Z0-9_] | Letters, digits, underscore | Same as \w |
[[:alpha:]] | POSIX: alphabetic characters | Used in tools like grep |
[[:digit:]] | POSIX: digit characters | Used in tools like sed |
Groups & References
| Pattern | Description | Example |
|---|---|---|
(abc) | Capturing group | (ha)+ matches haha |
(?:abc) | Non-capturing group | (?:ha)+ matches but doesn't capture |
(?<name>abc) | Named capturing group | (?<year>\d{4}) |
\1 | Backreference to group 1 | (["'])(.*?)\1 matches quoted strings |
\k<name> | Backreference to named group | \k<year> |
a|b | Alternation (a or b) | cat|dog matches either word |
(a|b)c | Group with alternation | (re|un)do matches redo, undo |
Lookahead & Lookbehind
| Pattern | Name | Description |
|---|---|---|
(?=abc) | Positive lookahead | Matches if followed by abc (doesn't consume) |
(?!abc) | Negative lookahead | Matches if NOT followed by abc |
(?<=abc) | Positive lookbehind | Matches if preceded by abc |
(?<!abc) | Negative lookbehind | Matches if NOT preceded by abc |
# Lookahead: match "foo" only if followed by "bar"
foo(?=bar) → matches "foo" in "foobar", not in "foobaz"
# Lookbehind: match digits preceded by "$"
(?<=\$)\d+ → matches "100" in "$100", not in "€100"
# Negative lookahead: match "foo" NOT followed by "bar"
foo(?!bar) → matches "foo" in "foobaz", not in "foobar"
Flags / Modifiers
| Flag | Name | Description |
|---|---|---|
g | Global | Match all occurrences, not just the first |
i | Case-insensitive | Match regardless of case |
m | Multiline | ^ and $ match start/end of each line |
s | Dotall / Single-line | . also matches newline characters |
u | Unicode | Enable full Unicode matching |
x | Extended / Verbose | Allow comments and whitespace in pattern (Python, PHP) |
// JavaScript: flags after closing /
const re = /hello/gi;
# Python: flags as argument
re.findall(r'hello', text, re.IGNORECASE)
# Inline flag (works in most engines)
(?i)hello
Common Patterns
| Use Case | Pattern |
|---|---|
| Email (simple) | [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} |
| URL | https?://[^\s/$.?#].[^\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} |
| Date (YYYY-MM-DD) | \d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01]) |
| Time (HH:MM) | (?:[01]\d|2[0-3]):[0-5]\d |
| Hex color | #(?:[0-9a-fA-F]{3}){1,2}\b |
| HTML tag | <([a-z]+)([^<]*?)(?:>(.*?)<\/\1>|\/>) |
| Username (3-16 chars) | ^[a-zA-Z0-9_-]{3,16}$ |
| Strong password | ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$ |
| Trailing whitespace | \s+$ |
| Duplicate words | \b(\w+)\s+\1\b |
| Comma-separated values | [^,]+ |
| Number with commas | \d{1,3}(,\d{3})*(\.\d+)? |
Warning: These patterns cover common cases but are not exhaustive validators. For production use (especially email and URL), consider using your language's built-in validation libraries.
Regex in Languages
JavaScript
const re = /\d+/g;
"abc 123 def 456".match(re); // ["123", "456"]
"hello".replace(/l/g, "L"); // "heLLo"
re.test("abc123"); // true
// Named groups
const m = "2026-05-08".match(/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/);
m.groups.y; // "2026"
Python
import re
re.findall(r'\d+', 'abc 123 def 456') # ['123', '456']
re.sub(r'l', 'L', 'hello') # 'heLLo'
re.search(r'\d+', 'abc123').group() # '123'
re.split(r'[,;]', 'a,b;c') # ['a', 'b', 'c']
# Named groups
m = re.search(r'(?P<year>\d{4})', '2026-05')
m.group('year') # '2026'
Bash (grep / sed)
# grep: find lines matching a pattern
grep -E '\d{3}-\d{4}' file.txt
grep -oP '(?<=@)\S+' emails.txt # extract domains
# sed: search and replace
sed -E 's/foo/bar/g' file.txt # replace all "foo" with "bar"
sed -n '/^Error/p' log.txt # print lines starting with "Error"