M
MeshWorld.
Cheatsheet Regex Regular Expressions JavaScript Python Developer Tools Terminal 5 min read

Regex Cheat Sheet: Patterns, Groups & Real Examples

By Vishnu Damwala

Quick reference tables

Anchors

PatternMatches
^Start of string (or line in multiline mode)
$End of string (or line in multiline mode)
\bWord boundary
\BNot a word boundary
\AStart of string (some engines)
\ZEnd of string (some engines)

Character classes

PatternMatches
.Any character except newline
\dDigit [0-9]
\DNot a digit
\wWord character [a-zA-Z0-9_]
\WNot a word character
\sWhitespace (space, tab, newline)
\SNot whitespace
[abc]a, b, or c
[^abc]Not a, b, or c
[a-z]Lowercase a through z
[A-Z]Uppercase A through Z
[0-9]Digit
[a-zA-Z0-9]Alphanumeric

Quantifiers

PatternMatches
*0 or more (greedy)
+1 or more (greedy)
?0 or 1 (optional)
{3}Exactly 3
{3,}3 or more
{3,6}Between 3 and 6
*?0 or more (lazy/non-greedy)
+?1 or more (lazy/non-greedy)
??0 or 1 (lazy)

Groups & references

PatternWhat it does
(abc)Capturing group
(?:abc)Non-capturing group
(?<name>abc)Named capturing group
\1Backreference to group 1
\k<name>Backreference to named group
(a|b)Alternation (a or b)

Lookaheads & lookbehinds

PatternWhat it does
x(?=y)x followed by y (positive lookahead)
x(?!y)x NOT followed by y (negative lookahead)
(?<=y)xx preceded by y (positive lookbehind)
(?<!y)xx NOT preceded by y (negative lookbehind)

Flags

FlagWhat it does
gGlobal (find all matches)
iCase-insensitive
mMultiline (^ and $ match line start/end)
sDotall (. matches newlines too)
uUnicode mode
dGenerate match indices (JS only)

Detailed sections

Common real-world patterns

# Email (basic — full RFC 5322 is much more complex)
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

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

# IP address (IPv4)
\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

# Phone number (flexible international)
^\+?[\d\s\-().]{7,15}$

# Date (YYYY-MM-DD)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

# Credit card (basic 16-digit)
\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b

# Hex color code
^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$

# Slug (URL-safe)
^[a-z0-9]+(?:-[a-z0-9]+)*$

# Semantic version
^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(alpha|beta|rc)\.?\d*)?$

# Strong password (8+ chars, upper, lower, digit, special)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

JavaScript — using regex

const email = "alice@example.com";
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

// Test — returns true/false
emailRegex.test(email); // true

// Match — returns array or null
const match = "2026-03-11".match(/^(\d{4})-(\d{2})-(\d{2})$/);
// ["2026-03-11", "2026", "03", "11"]

// Named groups
const dateRegex = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/;
const result = "2026-03-11".match(dateRegex);
result?.groups?.year;  // "2026"
result?.groups?.month; // "03"

// Replace
"Hello World".replace(/o/g, "0"); // "Hell0 W0rld"

// Replace with function
"hello world".replace(/\b\w/g, (char) => char.toUpperCase());
// "Hello World"

// Split
"one,two,,three".split(/,+/); // ["one", "two", "three"]

// Find all matches
const text = "Prices: $10.99, $25.50, $100.00";
const prices = [...text.matchAll(/\$(\d+\.\d{2})/g)];
prices.map(m => m[1]); // ["10.99", "25.50", "100.00"]

Grep — regex in terminal

# Basic search (ERE with -E)
grep -E "error|warning" app.log

# Case insensitive
grep -iE "error|warning" app.log

# Show line numbers
grep -nE "TODO|FIXME" src/*.ts

# Find lines that DON'T match
grep -vE "^#|^$" config.txt  # strip comments and blank lines

# Extract only the matching part (not whole line)
grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" access.log  # extract IPs

# Multiline match with context
grep -A 3 -B 1 "EXCEPTION" error.log  # 3 lines after, 1 before

# Count matches
grep -cE "200 OK" access.log

Lookahead tricks

// Positive lookahead: match "foo" only when followed by "bar"
"foobar foobaz".match(/foo(?=bar)/g); // ["foo"]

// Negative lookahead: match "foo" NOT followed by "bar"
"foobar foobaz".match(/foo(?!bar)/g); // ["foo"] (from foobaz)

// Password validation with multiple lookaheads
const strongPassword = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$]).{8,}$/;
strongPassword.test("Passw0rd!"); // true
strongPassword.test("password");  // false — no uppercase or digit or special

// Find duplicate words
const dupWords = /\b(\w+)\s+\1\b/gi;
"the the quick brown fox fox".match(dupWords); // ["the the", "fox fox"]

Python — regex

import re

# Compile for reuse
pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')

# Test
pattern.match('alice@example.com')  # Match object (truthy)
pattern.match('not-an-email')       # None (falsy)

# Find all
re.findall(r'\d+', 'a1 b2 c3')  # ['1', '2', '3']

# Named groups
m = re.match(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})', '2026-03-11')
m.group('year')   # '2026'
m.groupdict()     # {'year': '2026', 'month': '03', 'day': '11'}

# Substitute
re.sub(r'\s+', ' ', 'too   many    spaces')  # 'too many spaces'

# Split
re.split(r'[,;]\s*', 'one, two; three')  # ['one', 'two', 'three']

# Multiline
text = """line one
line two
line three"""
re.findall(r'(?m)^line \w+', text)
# ['line one', 'line two', 'line three']