Regex Cheatsheet — The 20 Patterns You'll Actually Use
Forget memorising every regex symbol. Here are the 20 patterns that solve 95% of real-world tasks — email, URL, phone, dates, capture groups, lookaheads.
Regex has a reputation for being arcane, but the truth is most real-world tasks need only 10-15 of the patterns. Memorize those, and you can solve the vast majority of "find this in text" problems you'll meet in JavaScript, Python, grep, your editor, or anywhere else.
This is the cheatsheet — the patterns you'll actually use, with examples in JavaScript-flavored regex. They translate almost unchanged to Python, PHP, Ruby and most other modern languages.
The basics — character classes
| Pattern | Matches |
|---|---|
. | Any single character except newline |
\d | A digit (0-9) |
\D | A non-digit |
\w | A word character (letters, digits, underscore) |
\W | A non-word character |
\s | Whitespace (space, tab, newline) |
\S | Non-whitespace |
[abc] | One of a, b, or c |
[^abc] | Anything except a, b, or c |
[a-z] | Any lowercase letter |
[a-zA-Z0-9] | Any alphanumeric |
Quantifiers — how many
| Pattern | Means |
|---|---|
* | 0 or more |
+ | 1 or more |
? | 0 or 1 (optional) |
{3} | Exactly 3 |
{3,} | 3 or more |
{3,5} | Between 3 and 5 |
By default quantifiers are greedy — they match as much as possible. Add ? after them to make them lazy (match as little as possible):
/<.*>/ matches the whole "<a><b><c>" string
/<.*?>/ matches just "<a>", then "<b>", then "<c>"Anchors — where it matches
^— start of string (or start of line with themflag)$— end of string (or end of line with themflag)\b— word boundary (between a word char and a non-word char)\B— non-word-boundary
/^Hello/ matches "Hello world" but not "say Hello"
/world$/ matches "hello world" but not "world hello"
/\bcat\b/ matches "the cat sat" but not "concatenate"The 20 patterns you'll actually use
1. Match an email (basic, good enough)
/^[^\s@]+@[^\s@]+\.[^\s@]+$/Not perfect — RFC-compliant email matching is famously horrible. This catches 99.9% of real emails and rejects obvious junk.
2. Match a URL
/^https?:\/\/[^\s]+$/Starts with http:// or https://, no spaces. Use a URL parser for serious validation.
3. Match an integer
/^-?\d+$/Optional minus sign, then one or more digits.
4. Match a decimal number
/^-?\d+(\.\d+)?$/Integer, optionally followed by a decimal part.
5. Match a date (YYYY-MM-DD)
/^\d{4}-\d{2}-\d{2}$/6. Match a time (HH:MM, 24h)
/^([01]\d|2[0-3]):[0-5]\d$/7. Match a US phone number
/^\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/Matches 555-555-5555, (555) 555-5555, 5555555555, etc.
8. Match a hex color
/^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/Matches #abc and #aabbcc.
9. Match an IPv4 address
/^(\d{1,3}\.){3}\d{1,3}$/Loose match. Doesn't validate each octet is 0-255 — that's harder than it should be.
10. Match a slug (lowercase, hyphens)
/^[a-z0-9]+(-[a-z0-9]+)*$/Useful for URL slugs and Hugo / Jekyll filenames.
11. Find whitespace and trim
text.replace(/^\s+|\s+$/g, '') // trim both ends
text.replace(/\s+/g, ' ') // collapse internal whitespace12. Remove HTML tags (simple)
text.replace(/<[^>]+>/g, '')Don't use this for security — use a proper HTML sanitizer (DOMPurify) for untrusted input. Fine for cleaning visible text from scraped content.
13. Capture groups
const match = "John Smith".match(/^(\w+)\s(\w+)$/);
// match[1] === "John"
// match[2] === "Smith"Parentheses create capture groups, accessible via the match array or in replacement strings as $1, $2, etc.
14. Named capture groups (cleaner)
const match = "2026-05-20".match(/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/);
// match.groups.year === "2026"
// match.groups.month === "05"15. Non-capturing group
/(?:foo|bar)baz/Use (?:...) when you need grouping but don't care about capturing — slightly faster and keeps your match indices clean.
16. Lookahead — match X followed by Y
/foo(?=bar)/Matches "foo" only when followed by "bar". The "bar" is NOT included in the match.
17. Negative lookahead — match X NOT followed by Y
/foo(?!bar)/Matches "foo" only when not followed by "bar". Classic use: match a year that's not 2020 — /202(?!0)\d/.
18. Lookbehind — match X preceded by Y
/(?<=USD)\d+/Matches digits preceded by "USD". The "USD" is not in the match.
19. Find duplicate words
/\b(\w+)\s+\1\b/gMatches "the the" or "cat cat" — useful for catching repeat-word typos in text. \\1 is a back-reference to the first captured group.
20. Split CSV line (handling quoted commas)
/(?:^|,)("(?:[^"]+|"")*"|[^,]*)/gMatches CSV fields, handling quoted fields that contain commas. Real CSV parsing has edge cases — for production use, use a real CSV parser (or our File Converter ).
Flags — modifying the match
g— global. Find all matches, not just the first.i— case-insensitive.m— multiline.^and$match start/end of each line, not the whole string.s— dotall..matches newlines too.u— unicode. Required for proper Unicode matching.
JavaScript regex API quick reference
// Test if a pattern matches
/^\d+$/.test("12345") // true
// Get first match
"hello world".match(/(\w+)/) // ["hello", "hello"]
// Get all matches with global flag
"hello world".match(/\w+/g) // ["hello", "world"]
// Modern way — matchAll returns iterator with groups
[..."hello world".matchAll(/(\w+)/g)]
// Replace
"hello world".replace(/world/, "there") // "hello there"
// Replace with capture group reference
"John Smith".replace(/(\w+) (\w+)/, "$2, $1") // "Smith, John"
// Split
"a,b,,c".split(/,/) // ["a", "b", "", "c"]Performance gotchas
- Catastrophic backtracking: patterns like
(a+)+bon a long string ofa's can hang the regex engine. Avoid nested quantifiers when possible. - Anchoring is fast:
^pattern$fails immediately if it can't match from the start. Add anchors when you know the match should cover the whole string. - Compile once, reuse: in JS, the same literal regex is reused. With
new RegExp(str), cache the result. - Atomic groups and possessive quantifiers (available in some engines) eliminate backtracking — useful for performance-critical patterns.
When NOT to use regex
- Parsing HTML or XML. Use a real parser. Regex can't handle nested structures correctly.
- Validating email addresses strictly. The full RFC is hundreds of lines. Either accept loose matching or send a confirmation email.
- Parsing programming languages. Tokenizers and ASTs exist for a reason.
- Trying to be clever. If your regex needs comments to explain it, it should probably be 2-3 simpler regexes or a real function.
Test your patterns before you ship
Building regex in your head is error-prone. Use a live tester — paste the pattern, paste sample text, see matches highlighted. The classic options:
- regex101.com — best free option, supports JavaScript / Python / PHP flavors.
- regexr.com — clean UI with explanations of each part of your pattern.
The 30-second rule: if a regex took you more than 30 seconds to write, write a test against 5 sample strings before shipping. Regex bugs are the most embarrassing kind.
Related tools: Text Case Converter, JSON Formatter, Code Beautifier and File Converter for safer alternatives to "let me just regex it".