iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Cheatsheet

A one-screen reference for the regex syntax you reach for daily — flavours, anchors, quantifiers, character classes, groups, lookarounds — plus the things that bite: greedy vs lazy, ReDoS shapes, and the "use a parser instead" cases.

Regex syntax + gotchas, one page

EXAMPLE
# ===== Flavours — pick the right doc =====
# JS:        ECMAScript regex (V8/SpiderMonkey/JSC). Lookbehinds since 2018.
# PCRE2:     Perl-compatible (PHP, nginx, learn-once tester). Most powerful.
# Python:    re module. Very close to PCRE; verbose mode is good for long patterns.
# Go:        RE2. No backreferences, linear-time. Great for untrusted input.
# Java:      java.util.regex. Similar to PCRE, supports named groups (?<name>).
# .NET:      System.Text.RegularExpressions. Best optimised regex engine.

# ===== Anchors =====
^         start of string (or line with multiline flag)
$         end of string (or line with multiline flag)
\b        word boundary
\B        not a word boundary
\A        start of input (Python/PCRE/Java/.NET)
\Z        end of input

# ===== Character classes =====
.         any character (NOT including newline by default — use 's' flag)
\d        digit (= [0-9])
\D        non-digit
\w        word char (= [a-zA-Z0-9_])
\W        non-word char
\s        whitespace
\S        non-whitespace
[abc]     literal class
[^abc]    negated class
[a-z]     range
\p{L}     Unicode letter (requires /u in JS, --pcre2 etc.)
\p{N}     Unicode digit
\p{Greek} Unicode script

# ===== Quantifiers =====
*         0 or more (greedy)
+         1 or more (greedy)
?         0 or 1
{n}       exactly n
{n,}      n or more
{n,m}     n to m

# Lazy variants (match as little as possible)
*?  +?  ??  {n,m}?

# Possessive (Java, PCRE) — no backtracking
*+  ++  ?+  {n,m}+

# ===== Groups =====
(abc)         capturing
(?:abc)       non-capturing
(?<name>abc)  named capture
\1 / \k<name> backreferences (NOT in RE2)
(?>abc)       atomic group (no backtracking inside)

# ===== Lookaround (zero-width) =====
(?=abc)       positive lookahead
(?!abc)       negative lookahead
(?<=abc)      positive lookbehind (variable length in modern PCRE/Java/.NET)
(?<!abc)      negative lookbehind

# ===== Flags / modifiers =====
i  case-insensitive
m  multiline (^ and $ match per line)
s  dotall (. matches newline)
u  Unicode (JS)
x  extended (ignore whitespace + allow comments — great for long patterns)

# ===== Common pitfalls =====

# Greedy by default
# 'a.*b' against 'aXXbYYb' matches 'aXXbYYb'. Use 'a.*?b' for 'aXXb'.

# Catastrophic backtracking (ReDoS)
# (a+)+$  against 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa!' -> exponential time
# Fixes:
# - Avoid nested quantifiers
# - Avoid (a|aa)*-style overlapping alternations
# - Use atomic groups (?>...) where supported
# - Use RE2 (Go) when patterns are user-supplied

# Email validation
# Use a permissive shape (^[^@]+@[^@]+\.[^@]+$) then verify by sending a token.
# Strict RFC 5321 regex rejects real addresses.

# CSV parsing
# Do NOT regex. csv libraries handle quoted commas, escaping, multi-line cells.

# HTML / XML / JSON parsing
# Do NOT regex. Use a real parser. The 'just one line' temptation leads to bugs.

# ===== Quick lookup recipes =====
# Trim:                     /^\s+|\s+$/g
# Words:                    /\b\w+\b/g
# IP-ish:                   /\b(?:\d{1,3}\.){3}\d{1,3}\b/  (then validate octets)
# Hex colour:               /^#(?:[0-9a-f]{3}){1,2}$/i
# UUID v4:                  /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
# ISO date (yyyy-mm-dd):    /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/
# Base64-ish:               /^[A-Za-z0-9+/]+={0,2}$/

# ===== Tools =====
# regex101.com    visual tester + explainer + code generator
# debuggex.com    railroad diagrams
# safe-regex      npm linter that detects exponential patterns
# rxxr2           research-grade ReDoS analysis

Why it matters

Compile patterns once (module/file level) when you re-use them across rows, never recompile inside a loop. The engines internal cache helps a bit, but explicit compile() removes the per-call lookup and turns hot-path regex from "slow" into "the right tool for the job".

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// . ^ $ * + ? | ( ) [ ] { } \b \d \w \s | i g m s u y | (?:) (?=) (?!) (?<=) (?<!)
Try it Yourself »

Discussion

Loading…