Regular expressions are one of those skills that pay off every time you need to search, validate, or transform text. This cheat sheet covers the most-used patterns with examples you can test immediately.

Open the live regex tester →

Character Classes

PatternMatches
.Any character except newline
\dDigit [0-9]
\DNon-digit
\wWord character [a-zA-Z0-9_]
\WNon-word character
\sWhitespace (space, tab, newline)
\SNon-whitespace
[abc]One of: a, b, or c
[^abc]Not a, b, or c
[a-z]Lowercase letter a through z
[A-Z]Uppercase letter A through Z
[0-9]Digit 0 through 9

Anchors

PatternMatches
^Start of string (or line in multiline mode)
$End of string (or line in multiline mode)
\bWord boundary
\BNon-word boundary
/^\d{5}$/    → matches exactly a 5-digit ZIP code
/\bword\b/   → matches "word" but not "password"

Quantifiers

PatternMeaning
*0 or more
+1 or more
?0 or 1 (optional)
{n}Exactly n times
{n,}n or more times
{n,m}Between n and m times

Greedy vs lazy: by default quantifiers are greedy (match as much as possible). Add ? to make them lazy:

<.+>    → greedy: matches <b>bold</b> entirely
<.+?>   → lazy: matches <b> then </b> separately

Groups and Alternation

PatternMeaning
(abc)Capture group
(?:abc)Non-capturing group
a|bAlternation: a or b
\1Backreference to group 1
// Extract year, month, day from a date string
const match = '2026-04-03'.match(/(\d{4})-(\d{2})-(\d{2})/);
// match[1] = '2026', match[2] = '04', match[3] = '03'

Lookaheads and Lookbehinds

PatternMeaning
(?=abc)Positive lookahead — followed by abc
(?!abc)Negative lookahead — not followed by abc
(?<=abc)Positive lookbehind — preceded by abc
(?<!abc)Negative lookbehind — not preceded by abc
/\d+(?= dollars)/   → matches digits only when followed by " dollars"
/(?<=\$)\d+/        → matches digits only when preceded by "$"

Lookbehind requires ES2018+ in JavaScript.

Flags

FlagEffect
iCase-insensitive
gGlobal — find all matches
mMultiline — ^ and $ match line boundaries
sDotall — . also matches newline
uUnicode mode
/hello/i.test('Hello World')  // true
'abc abc'.match(/abc/g)       // ['abc', 'abc']

Common Patterns

Email (basic)

/^[^\s@]+@[^\s@]+\.[^\s@]+$/

URL

/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/

IPv4 Address

/^(\d{1,3}\.){3}\d{1,3}$/

Hex Color

/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/

US Phone Number

/^(\+1\s?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/

Slug (URL-friendly string)

/^[a-z0-9]+(?:-[a-z0-9]+)*$/

Semver

/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*))?(?:\+([\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*))?$/

Using Regex in Code

JavaScript

// Test if a string matches
/^\d+$/.test('123')       // true
/^\d+$/.test('12a')       // false

// Find first match
'hello world'.match(/\w+/)    // ['hello']

// Find all matches
'hello world'.match(/\w+/g)   // ['hello', 'world']

// Replace
'foo bar'.replace(/\b\w/g, c => c.toUpperCase())  // 'Foo Bar'

// Split
'one, two,three'.split(/,\s*/)  // ['one', 'two', 'three']

Python

import re

# Test
bool(re.match(r'^\d+$', '123'))        # True

# Find first
re.search(r'\d+', 'abc123def')         # match object
re.search(r'\d+', 'abc123def').group() # '123'

# Find all
re.findall(r'\d+', 'a1 b22 c333')      # ['1', '22', '333']

# Replace
re.sub(r'\s+', '-', 'hello world')     # 'hello-world'

Test Your Regex Live

Writing a pattern? Test it before shipping — edge cases are easy to miss.

ZeroTool Regex Tester →

  • Paste your pattern and test string
  • See all matches highlighted in real time
  • Supports flags: g, i, m, s
  • Shows capture group results

Debugging Tips

  1. Start simple — build the pattern piece by piece
  2. Use raw strings in Pythonr'\d+' avoids double-escaping
  3. Escape special chars., *, +, ?, (, ), [, ], {, }, ^, $, |, \ all need escaping when used literally
  4. Anchor when you mean it/\d+/ matches digits anywhere; /^\d+$/ requires the entire string to be digits
  5. Test with boundary cases — empty string, all matches, no match, overlapping patterns

Regex is powerful but can become unmaintainable fast. If a pattern exceeds ~60 characters, consider breaking it into named sub-patterns or using a parser library instead.