Every developer eventually hits that moment — you need to validate an email, extract a date from a log file, or clean up some messy user input, and you end up on Stack Overflow copying a regex pattern you barely understand. No shame in that. I still look up regex syntax for things I don't use daily.
This cheat sheet is the reference I wish I had when I started. Not a textbook on regex theory — just practical, copy-paste ready patterns organized by what you're actually trying to do. Every pattern is tested, explained, and ready for production use.
Regex Syntax Quick Reference
Before diving into patterns, here's the core syntax you need to know:
| Symbol | Meaning | Example |
|---|---|---|
| . | Any character (except newline) | a.b → acb, a1b, a-b |
| \d | Any digit (0-9) | \d{3} → 123, 456 |
| \w | Word character (a-z, A-Z, 0-9, _) | \w+ → hello_world |
| \s | Whitespace (space, tab, newline) | a\sb → a b, a\tb |
| ^ | Start of string | ^Hello → Hello world |
| $ | End of string | world$ → Hello world |
| * | Zero or more | ab*c → ac, abc, abbc |
| + | One or more | ab+c → abc, abbc (not ac) |
| ? | Zero or one (optional) | colou?r → color, colour |
| {n} | Exactly n times | \d{4} → 2026 |
| {n,m} | Between n and m times | \d{2,4} → 12, 123, 1234 |
| [abc] | Character set (a, b, or c) | [aeiou] → any vowel |
| [^abc] | Not a, b, or c | [^0-9] → non-digit |
| (group) | Capture group | (\d+)-(\d+) → 123-456 |
| (?:group) | Non-capturing group | (?:ab)+ → abab |
| a|b | OR (a or b) | cat|dog → cat, dog |
| \b | Word boundary | \bword\b → exact match |
Validation Patterns
These are the patterns you'll use most often — validating user input before it hits your database.
Email address
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$Handles 99% of real emails. For full RFC 5322 compliance, use a library.
✓ Matches: user@example.com, name+tag@sub.domain.co.uk
✗ Fails: @example.com, user@.com
URL (http/https)
^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)$Matches full URLs with optional www, path, and query string.
✓ Matches: https://example.com/path?q=1
✗ Fails: ftp://file.com, just-text
Phone (international)
^\+?[1-9]\d{1,14}$E.164 format. Up to 15 digits with optional + prefix.
✓ Matches: +14155552671, 442071234567
✗ Fails: 0000, +0123
Phone (US formats)
^(\+1)?[-. ]?\(?\d{3}\)?[-. ]?\d{3}[-. ]?\d{4}$Handles +1, parentheses, dashes, dots, spaces.
✓ Matches: (555) 123-4567, +1-555-123-4567
✗ Fails: 12345, 555-12-34567
IPv4 address
^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$Validates each octet is 0-255. Rejects 999.999.999.999.
✓ Matches: 192.168.1.1, 10.0.0.255
✗ Fails: 256.1.1.1, 1.2.3
IPv6 address (simplified)
^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$Full IPv6 without shorthand. For :: notation, use a library.
✓ Matches: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
✗ Fails: ::1 (shorthand)
Date (YYYY-MM-DD)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ISO 8601 format. Validates month 01-12, day 01-31.
✓ Matches: 2026-06-29, 2024-12-31
✗ Fails: 2024-13-01, 2024-00-15
Time (HH:MM:SS)
^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$24-hour format.
✓ Matches: 23:59:59, 00:00:00
✗ Fails: 24:00:00, 12:60:00
Hex color code
^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$3, 6, or 8 digit hex with # prefix. 8-digit includes alpha.
✓ Matches: #fff, #4f46e5, #4f46e5ff
✗ Fails: #gg, #12345
UUID v4
^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$Validates UUID v4 format with correct version/variant bits.
✓ Matches: 550e8400-e29b-41d4-a716-446655440000
✗ Fails: not-a-uuid
Credit card (basic)
^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})$Visa, Mastercard, Amex. For production, use a payment library.
✓ Matches: 4111111111111111 (Visa test)
✗ Fails: 1234567890
Strong password
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$Min 8 chars, uppercase, lowercase, digit, special character.
✓ Matches: P@ssw0rd!
✗ Fails: password, Pass1234
String Extraction & Parsing Patterns
These patterns pull specific data out of messy strings — log files, HTML, CSV, you name it.
Extract all numbers
\d+Finds every sequence of digits in a string.
→ 'Order #123 has 5 items' → ['123', '5']
Extract decimal numbers
-?\d+\.?\d*Includes negatives and decimals.
→ 'Price: -12.50 and 3.14' → ['-12.50', '3.14']
Extract all emails from text
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}Finds emails embedded in any text (no anchors).
→ 'Contact alice@dev.com or bob@test.io' → ['alice@dev.com', 'bob@test.io']
Extract URLs from text
https?:\/\/[^\s<>"]+Finds http/https URLs in running text.
→ 'Visit https://example.com for details' → ['https://example.com']
Extract hashtags
#[a-zA-Z0-9_]+Social media hashtag extraction.
→ 'Love #javascript and #webdev' → ['#javascript', '#webdev']
Extract @mentions
@[a-zA-Z0-9_]+Social media mention extraction.
→ 'Thanks @alice and @bob_dev' → ['@alice', '@bob_dev']
Extract between quotes
["']([^"']+)["']Captures text inside single or double quotes.
→ 'She said "hello world"' → ['hello world']
Extract between parentheses
\(([^)]+)\)Captures content inside parentheses.
→ 'func(arg1, arg2)' → ['arg1, arg2']
Extract HTML tag content
<([a-z]+)[^>]*>(.*?)<\/\1>Captures tag name + inner content. Don't use for complex HTML parsing.
→ '<p>Hello</p>' → tag: 'p', content: 'Hello'
Extract query parameters
[?&]([^=]+)=([^&#]*)Parses URL query string key-value pairs.
→ '?name=alice&age=30' → [['name','alice'], ['age','30']]
Extract file extension
\.([a-zA-Z0-9]+)$Gets the extension from a filename.
→ 'document.pdf' → 'pdf'
Extract domain from URL
https?:\/\/(?:www\.)?([^/]+)Pulls just the domain name.
→ 'https://www.example.com/path' → 'example.com'
Text Cleaning & Manipulation Patterns
Use these with replace() to clean, transform, or format strings.
Remove HTML tags
Pattern: <[^>]+>Replace: ''→ '<p>Hello <b>world</b></p>' → 'Hello world'
Collapse whitespace
Pattern: \s+Replace: ' '→ 'hello world\n\t!' → 'hello world !'
Trim leading/trailing spaces
Pattern: ^\s+|\s+$Replace: ''→ ' hello ' → 'hello'
Remove non-alphanumeric
Pattern: [^a-zA-Z0-9]Replace: ''→ 'Hello, World! #123' → 'HelloWorld123'
CamelCase to kebab-case
Pattern: ([a-z])([A-Z])Replace: '$1-$2'.toLowerCase()→ 'backgroundColor' → 'background-color'
Remove duplicate lines
Pattern: ^(.*)$\n(?=.*^\1$)Replace: '' (with gm flags)→ Removes exact duplicate lines from multiline text
Mask credit card number
Pattern: \d{4}(?=\d{4})Replace: '****'→ '4111111111111111' → '************1111'
Format phone number
Pattern: (\d{3})(\d{3})(\d{4})Replace: '($1) $2-$3'→ '5551234567' → '(555) 123-4567'
Slug generator
Pattern: [^a-z0-9]+Replace: '-' (after toLowerCase())→ 'Hello World! #123' → 'hello-world-123'
Remove comments (JS)
Pattern: \/\/.*$|\/\*[\s\S]*?\*\/Replace: ''→ Strips // and /* */ comments from code
Using Regex in Code (JavaScript & Python)
JavaScript — Common Operations
// Test if string matches pattern
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
emailRegex.test("user@example.com") // → true
// Find all matches
const text = "Call 555-1234 or 555-5678"
const phones = text.match(/\d{3}-\d{4}/g) // → ['555-1234', '555-5678']
// Replace with regex
const cleaned = "Hello World".replace(/\s+/g, " ") // → "Hello World"
// Named capture groups (ES2018+)
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const { groups } = "2026-06-29".match(dateRegex)
// groups.year → "2026", groups.month → "06", groups.day → "29"
// Split by regex
"one, two; three".split(/[,;]\s*/) // → ['one', 'two', 'three']
// Replace with function
"hello world".replace(/\b\w/g, c => c.toUpperCase()) // → "Hello World"Python — Common Operations
import re
# Test if string matches
if re.match(r'^[\w.+-]+@[\w-]+\.[\w.]+$', email):
print("Valid email")
# Find all matches
phones = re.findall(r'\d{3}-\d{4}', "Call 555-1234 or 555-5678")
# → ['555-1234', '555-5678']
# Replace
cleaned = re.sub(r'\s+', ' ', "Hello World") # → "Hello World"
# Named groups
match = re.search(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})', "2026-06-29")
match.group('year') # → "2026"
# Compile for reuse (faster in loops)
PHONE_RE = re.compile(r'\(?(\d{3})\)?[-.\s]?(\d{3})[-.\s]?(\d{4})')
PHONE_RE.findall(text)Lookahead & Lookbehind (Advanced)
These patterns match a position without consuming characters — useful when you need context around a match without including it in the result.
| Type | Syntax | Meaning | Example |
|---|---|---|---|
| Positive lookahead | X(?=Y) | X followed by Y | \d+(?=px) → '12' in '12px' |
| Negative lookahead | X(?!Y) | X NOT followed by Y | \d+(?!px) → '34' in '34em' |
| Positive lookbehind | (?<=Y)X | X preceded by Y | (?<=\$)\d+ → '99' in '$99' |
| Negative lookbehind | (?<!Y)X | X NOT preceded by Y | (?<!\$)\d+ → '42' in 'item42' |
// Password validation using lookaheads (check multiple rules without consuming)
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$/
// Add commas to numbers (lookahead for groups of 3 digits)
"1234567".replace(/\B(?=(\d{3})+(?!\d))/g, ",") // → "1,234,567"
// Match word NOT preceded by specific text
/(?<!un)happy/ // Matches "happy" but NOT "unhappy"Regex Flags Reference
| Flag | Name | Effect |
|---|---|---|
| g | Global | Find ALL matches, not just the first one |
| i | Case-insensitive | A matches a, B matches b |
| m | Multiline | ^ and $ match start/end of each line (not just string) |
| s | Dotall | . matches newline characters too |
| u | Unicode | Enables \p{} unicode property escapes and correct surrogate handling |
| y | Sticky | Matches only at lastIndex position (no scanning forward) |
Common Regex Mistakes
⚠️ Forgetting to escape special characters
Characters like . * + ? need backslash to match literally. Without escaping, '.' matches ANY character, not just a period.
⚠️ Greedy matching when you want lazy
By default .* grabs as much as possible. Use .*? for the shortest match. '<b>one</b> and <b>two</b>' with /<b>.*</b>/ matches everything between the FIRST <b> and LAST </b>.
⚠️ Missing the global flag
Without /g, .match() and .replace() only process the first occurrence. Add g to handle all matches in the string.
⚠️ Using regex for complex HTML parsing
Regex can't handle nested tags, attributes with quotes, or malformed HTML reliably. Use DOMParser or a library like cheerio instead.
⚠️ Catastrophic backtracking (ReDoS)
Nested quantifiers like (a+)+ create exponential time on certain inputs. Avoid patterns like (.+)+ or (.*a){10}. Can crash your server.
⚠️ Not anchoring validation patterns
Without ^ and $, your pattern matches a SUBSTRING. /\d{3}/ matches '12345' because it contains 3 digits somewhere. Use /^\d{3}$/ to require exactly 3.
Frequently Asked Questions
What is a regex cheat sheet?
What are the most common regex patterns?
Is regex the same in all programming languages?
How do I test regex patterns?
What does the g flag do in regex?
How do I match special characters in regex?
What is the difference between * and + in regex?
Can regex be used for input validation?
Related Articles & Tools
Conclusion
Bookmark this page. Seriously. Regex isn't something you memorize — it's something you look up, test, and adapt. The patterns above cover the vast majority of real-world use cases you'll encounter in web development.
Start with the validation patterns (email, URL, phone) since those come up in almost every project. Then gradually learn the extraction and manipulation patterns as you need them. Use our Regex Tester to experiment with patterns in real time before dropping them into your code.
