← Back to Cheat Sheets
kavklaw@llm ~ /cheatsheets/regex

kavklaw@llm $ cat regex-cheatsheet.md

Regex Cheat Sheet

Metacharacters, quantifiers, groups, lookarounds, and battle-tested patterns.

Metacharacters

.         Any character except newline
\d        Digit [0-9]
\D        Non-digit [^0-9]
\w        Word character [a-zA-Z0-9_]
\W        Non-word character [^a-zA-Z0-9_]
\s        Whitespace [ \t\n\r\f\v]
\S        Non-whitespace
\b        Word boundary
\B        Non-word boundary
\\        Literal backslash
\.        Literal dot
\n        Newline
\t        Tab
\r        Carriage return

Anchors

^         Start of string (or line in multiline mode)
$         End of string (or line in multiline mode)
\A        Start of string (never affected by multiline)
\Z        End of string (never affected by multiline)
\b        Word boundary (between \w and \W)
\B        Non-word boundary

Examples:
^admin          String starts with "admin"
admin$          String ends with "admin"
^admin$         String is exactly "admin"
\bword\b        Match "word" as a whole word

Quantifiers

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

# Greedy vs Lazy (non-greedy)
*?        0 or more (lazy — match as few as possible)
+?        1 or more (lazy)
??        0 or 1 (lazy)
{n,m}?    Between n and m (lazy)

Examples:
a.*b      Greedy: "aXXXbYYYb" → matches "aXXXbYYYb"
a.*?b     Lazy:   "aXXXbYYYb" → matches "aXXXb"
colou?r   Matches "color" and "colour"
\d{3}     Exactly 3 digits
\d{2,4}   2 to 4 digits

Character Classes

[abc]         Match a, b, or c
[^abc]        Match anything except a, b, or c
[a-z]         Lowercase letter
[A-Z]         Uppercase letter
[0-9]         Digit (same as \d)
[a-zA-Z]      Any letter
[a-zA-Z0-9]   Alphanumeric (same as \w minus underscore)
[^a-z]        Not a lowercase letter
[-]           Literal hyphen (at start or end of class)
[.]           Literal dot (inside class, most special chars are literal)

# POSIX classes (used in grep, sed, awk):
[:alpha:]     Letters             [[:alpha:]]
[:digit:]     Digits              [[:digit:]]
[:alnum:]     Alphanumeric        [[:alnum:]]
[:upper:]     Uppercase           [[:upper:]]
[:lower:]     Lowercase           [[:lower:]]
[:space:]     Whitespace          [[:space:]]
[:punct:]     Punctuation         [[:punct:]]
[:xdigit:]    Hex digits          [[:xdigit:]]

Groups & Alternation

(abc)         Capturing group — matches "abc", stores in \1
(?:abc)       Non-capturing group — matches "abc", no capture
(?P<name>abc)  Named group — access by name (Python)
(?'name'abc)  Named group (.NET/PCRE)
a|b           Alternation — match "a" or "b"
(a|b)c        Match "ac" or "bc"

# Backreferences
\1            Reference to group 1
\2            Reference to group 2
(?P=name)     Reference to named group (Python)

Examples:
(ha)+         Match "ha", "haha", "hahaha"...
(\w+)\s\1     Match repeated words: "the the", "is is"
(cat|dog)     Match "cat" or "dog"

Lookaheads & Lookbehinds

# Lookahead (peek ahead without consuming)
(?=abc)       Positive lookahead — next chars ARE "abc"
(?!abc)       Negative lookahead — next chars are NOT "abc"

# Lookbehind (peek behind without consuming)
(?<=abc)      Positive lookbehind — preceding chars ARE "abc"
(?<!abc)      Negative lookbehind — preceding chars are NOT "abc"

Examples:
\d+(?= dollars)     Match digits followed by " dollars" (don't capture " dollars")
                     "100 dollars" → captures "100"
(?<=\$)\d+           Match digits preceded by "$"
                     "$50" → captures "50"
\b\w+(?!ing\b)      Match words NOT ending in "ing"
(?<!un)happy         Match "happy" NOT preceded by "un"

# Password validation (all of these at once):
^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$
  │           │           │          │           │
  │           │           │          │           └─ At least 8 chars
  │           │           │          └─ Has special char
  │           │           └─ Has digit
  │           └─ Has lowercase
  └─ Has uppercase

Flags / Modifiers

Flag    Name            Effect
────    ────            ──────
i       Case-insensitive   /admin/i matches "Admin", "ADMIN"
g       Global             Match all occurrences (not just first)
m       Multiline          ^ and $ match line boundaries
s       Dotall/SingleLine  . matches newline too
x       Verbose/Extended   Allow whitespace and comments in regex
u       Unicode            Full Unicode matching

# Python inline flags:
(?i)admin       Case-insensitive
(?m)^line       Multiline
(?s).*          Dotall

# In Python code:
import re
re.search(r"admin", text, re.IGNORECASE | re.MULTILINE)

Common Patterns

IP Addresses

# IPv4 (simple — matches invalid IPs like 999.999.999.999)
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}

# IPv4 (strict — 0-255 per octet)
\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b

# IPv4 with CIDR
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}

# IPv6 (simplified)
(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}

# Extract IPs from text:
grep -oP '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' file.txt

Email

# Basic email
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}

# RFC 5322 (simplified but more accurate)
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)

URLs & Domains

# URL (HTTP/HTTPS)
https?://[^\s/$.?#].[^\s]*

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

# Domain name
(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}

# Extract domains from text:
grep -oP '(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}' file.txt

Other Useful Patterns

# MAC address
(?:[0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}

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

# Phone number (US)
(?:\+?1[-.\s]?)?(?:\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}

# Social Security Number
\b\d{3}-\d{2}-\d{4}\b

# Hash patterns
[a-fA-F0-9]{32}       MD5
[a-fA-F0-9]{40}       SHA-1
[a-fA-F0-9]{64}       SHA-256

# Base64 string
[A-Za-z0-9+/]{4,}={0,2}

# JWT token
eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*

# Windows file path
[a-zA-Z]:\\(?:[^\\\/:*?"<>|\r\n]+\\)*[^\\\/:*?"<>|\r\n]*

# Linux file path
(?:/[^\s/]+)+

grep Regex

# Basic regex (BRE) — default grep
grep "pattern" file                    # Basic regex
grep -i "pattern" file                 # Case insensitive
grep -n "pattern" file                 # Show line numbers
grep -c "pattern" file                 # Count matches
grep -v "pattern" file                 # Invert (non-matching)
grep -o "pattern" file                 # Only matching part
grep -r "pattern" dir/                 # Recursive

# Extended regex (ERE) — use -E or egrep
grep -E "(cat|dog)" file               # Alternation
grep -E "\d+" file                     # One or more digits
grep -E "^(#|$)" file                  # Comments or empty lines

# Perl regex (PCRE) — use -P
grep -P "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" file  # IP addresses
grep -P "(?<=password=)\S+" file       # Lookbehind — text after "password="
grep -oP '(?<=href=")[^"]+' file       # Extract URLs from href

# BRE vs ERE differences:
# BRE: \( \) \{ \} \| need backslashes
# ERE: ( ) { } | work without backslashes
grep "ab\(cd\)\+" file                 # BRE: group + repetition
grep -E "ab(cd)+" file                 # ERE: same thing, cleaner

sed Regex

# sed uses BRE by default, -E for ERE

# Basic substitution
sed 's/old/new/' file                  # First match per line
sed 's/old/new/g' file                 # All matches
sed 's/old/new/gi' file                # All matches, case-insensitive

# Using groups
sed 's/\(.*\)@\(.*\)/User: \1, Domain: \2/' emails.txt
sed -E 's/(.*)@(.*)/User: \1, Domain: \2/' emails.txt  # ERE version

# Delete lines matching pattern
sed '/^#/d' file                       # Delete comment lines
sed '/^$/d' file                       # Delete empty lines

# Print only matching lines
sed -n '/pattern/p' file               # Like grep

# Replace IP addresses
sed -E 's/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/REDACTED/g' file

# Extract between delimiters
sed -n 's/.*password="\([^"]*\)".*/\1/p' file

awk Regex

# awk uses ERE natively (no -E needed)

# Match lines containing pattern
awk '/pattern/' file                   # Print matching lines
awk '/^root/' /etc/passwd              # Lines starting with "root"
awk '!/^#/' file                       # Lines NOT starting with #

# Match specific field
awk -F: '$1 ~ /admin/' /etc/passwd     # Field 1 matches "admin"
awk -F: '$1 !~ /nologin/' /etc/passwd  # Field 1 doesn't match

# Substitute
awk '{gsub(/old/, "new"); print}' file # Global substitution
awk '{sub(/first/, "replaced"); print}' file  # First match only

# Extract with regex
awk 'match($0, /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) {print substr($0, RSTART, RLENGTH)}' file

Python Regex (re module)

import re

text = "Call 123-456-7890 or 987-654-3210"

# Search (first match)
m = re.search(r"\d{3}-\d{3}-\d{4}", text)
if m:
    print(m.group())       # 123-456-7890
    print(m.start())       # Position 5

# Find all matches
phones = re.findall(r"\d{3}-\d{3}-\d{4}", text)
# ['123-456-7890', '987-654-3210']

# Find all with groups
pairs = re.findall(r"(\d{3})-(\d{3})-(\d{4})", text)
# [('123', '456', '7890'), ('987', '654', '3210')]

# Substitution
clean = re.sub(r"\d{3}-\d{3}-\d{4}", "REDACTED", text)

# Split
parts = re.split(r"[,;\s]+", "one, two; three four")

# Compile (reuse pattern)
pattern = re.compile(r"\b\w+@\w+\.\w+\b", re.IGNORECASE)
emails = pattern.findall(text)

# Named groups
m = re.search(r"(?P<area>\d{3})-(?P<num>\d{3}-\d{4})", text)
if m:
    print(m.group("area"))  # 123

Quick Regex Testing

# Test regex from command line:
echo "test 192.168.1.1 string" | grep -oP '\d+\.\d+\.\d+\.\d+'

# Python one-liner:
python3 -c "import re; print(re.findall(r'\d+\.\d+\.\d+\.\d+', 'IP is 10.10.10.5'))"

# Online testers:
# regex101.com  — best for testing with explanation
# regexr.com    — visual regex tester
# debuggex.com  — railroad diagram visualization