Regular Expressions Cheat Sheet for Developers
Regular expressions are one of the most powerful tools in a developer's toolkit — and one of the most frustrating to learn. This cheat sheet covers the syntax you'll actually use, with practical examples for every pattern.
Basic Matchers
| Pattern | Matches | Example |
|---|---|---|
. | Any character except newline | a.c matches abc, a1c, a-c |
\d | Any digit (0-9) | \d\d\d matches 123 |
\D | Any non-digit | \D+ matches abc |
\w | Word char (a-z, A-Z, 0-9, _) | \w+ matches hello_world |
\W | Non-word character | \W matches @, !, space |
\s | Whitespace (space, tab, newline) | \s+ matches |
\S | Non-whitespace | \S+ matches hello |
Anchors
| Pattern | Matches | Example |
|---|---|---|
^ | Start of string/line | ^Hello matches Hello world but not Say Hello |
$ | End of string/line | world$ matches Hello world |
\b | Word boundary | \bcat\b matches cat but not category |
\B | Non-word boundary | \Bcat\B matches the cat in location |
Quantifiers
| Pattern | Meaning | Example |
|---|---|---|
* | 0 or more | ab*c matches ac, abc, abbc |
+ | 1 or more | ab+c matches abc, abbc but not ac |
? | 0 or 1 (optional) | colou?r matches color and colour |
{3} | Exactly 3 | \d{3} matches 123 |
{2,4} | Between 2 and 4 | \d{2,4} matches 12, 123, 1234 |
{2,} | 2 or more | a{2,} matches aa, aaa, aaaa... |
Greedy vs. lazy: By default, quantifiers are greedy (match as much as possible). Add ? to make them lazy (match as little as possible):
// Greedy: .* matches everything
"<div>hello</div><div>world</div>".match(/<div>.*<\/div>/)
// Matches: "<div>hello</div><div>world</div>"
// Lazy: .*? matches as little as possible
"<div>hello</div><div>world</div>".match(/<div>.*?<\/div>/)
// Matches: "<div>hello</div>" Character Classes
| Pattern | Matches |
|---|---|
[abc] | Any of a, b, or c |
[^abc] | Any character except a, b, c |
[a-z] | Any lowercase letter |
[A-Za-z] | Any letter |
[0-9] | Any digit (same as \d) |
[a-zA-Z0-9_] | Any word character (same as \w) |
Groups and Alternation
// Capturing group - extracts matched text
/(\d{4})-(\d{2})-(\d{2})/.exec("2026-03-09")
// Groups: ["2026-03-09", "2026", "03", "09"]
// Named capturing group
/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/.exec("2026-03-09")
// groups: { year: "2026", month: "03", day: "09" }
// Non-capturing group (grouping without capturing)
/(?:http|https):\/\//
// Groups for alternation but doesn't capture
// Alternation (OR)
/cat|dog/ // Matches "cat" or "dog"
/(red|blue) car/ // Matches "red car" or "blue car" Lookaheads and Lookbehinds
These match a position without consuming characters. They're zero-width assertions:
| Pattern | Name | Meaning |
|---|---|---|
(?=...) | Positive lookahead | Followed by ... |
(?!...) | Negative lookahead | NOT followed by ... |
(?<=...) | Positive lookbehind | Preceded by ... |
(?<!...) | Negative lookbehind | NOT preceded by ... |
// Match a number followed by "px"
/\d+(?=px)/.exec("font-size: 16px") // "16"
// Match a word NOT followed by a comma
/\w+(?!,)/
// Match a number preceded by "$"
/(?<=\$)\d+/.exec("Price: $42") // "42"
// Match "script" NOT preceded by "Java"
/(?<!Java)script/ Flags
| Flag | Name | Effect |
|---|---|---|
g | Global | Find all matches, not just the first |
i | Case-insensitive | /hello/i matches Hello, HELLO |
m | Multiline | ^ and $ match line starts/ends |
s | Dotall | . matches newline characters too |
u | Unicode | Enables full Unicode support |
Common Real-World Patterns
Email Address (simplified)
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ Note: A fully RFC-compliant email regex is absurdly long. For production, use your language's email validation library.
URL
/https?:\/\/[^\s/$.?#].[^\s]*/i IPv4 Address
/^(\d{1,3}\.)3\d{1,3}$/ This validates the format but not the range (allows 999.999.999.999). For strict validation, check each octet is 0-255.
Phone Number (US formats)
/^(\+1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/ Matches: (555) 123-4567, 555-123-4567, +1 555.123.4567
Date (YYYY-MM-DD)
/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/ Hex Color
/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/ Matches: #fff, #FF5733
HTML Tags
/<([a-z][a-z0-9]*)\b[^>]*>(.*?)<\/\1>/gi Warning: Don't parse HTML with regex for anything serious. Use a proper HTML parser. This is fine for quick search-and-replace tasks.
Password Strength
// At least 8 chars, 1 uppercase, 1 lowercase, 1 digit, 1 special
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/ Whitespace Cleanup
// Trim leading/trailing whitespace
str.replace(/^\s+|\s+$/g, '')
// Collapse multiple spaces to one
str.replace(/\s+/g, ' ')
// Remove blank lines
str.replace(/^\s*\n/gm, '') JavaScript Regex Methods
| Method | Returns | Use Case |
|---|---|---|
str.match(regex) | Array of matches or null | Find matches |
str.matchAll(regex) | Iterator of match objects | Find all with groups |
str.replace(regex, str) | New string | Find and replace |
str.search(regex) | Index or -1 | Find position |
str.split(regex) | Array of parts | Split by pattern |
regex.test(str) | Boolean | Check if matches |
regex.exec(str) | Match object or null | Detailed match info |
Tips for Writing Better Regex
- Start simple, add complexity — Get the basic pattern working first, then handle edge cases.
- Use named groups —
(?<year>\d{4})is clearer than(\d{4})when you have multiple groups. - Avoid catastrophic backtracking — Nested quantifiers like
(a+)+can cause exponential runtime. Use atomic groups or possessive quantifiers when available. - Test with edge cases — Empty strings, very long input, Unicode characters, and newlines often break regex patterns.
- Add comments — Use the
xflag (verbose mode) in Python/Ruby to add whitespace and comments to complex patterns. - Use a testing tool — Try our Regex Tester to build and debug patterns interactively with highlighted matches.
Regex is a skill that improves with practice. Bookmark this cheat sheet for reference, and use our Regex Tester to experiment with patterns in real-time.