Learning & reference

Regex cheat sheet

Every token you actually use, the flags that change everything, ready-made patterns you can paste straight in, and the traps that turn a working regex into a production incident.

Character classes

TokenMatchesExample
.Any character except newline (unless the s flag is set)a.c matches abc, a c
\dA digit, 0-9\d{4} matches 2026
\DAnything that is not a digit
\wWord character: letter, digit or underscore\w+ matches user_1
\WAnything that is not a word character
\sWhitespace: space, tab, newline\s+ collapses runs of spaces
\SAnything that is not whitespace
[abc]Any one of a, b or c[aeiou] matches a vowel
[^abc]Any character except a, b or c
[a-z]A range[A-Za-z0-9] is alphanumeric

Anchors & boundaries

TokenMatchesExample
^Start of the string (or of a line with the m flag)^Error
$End of the string (or of a line with m)\.log$
\bA word boundary\bcat\b matches cat but not concatenate
\BNot a word boundary

Quantifiers

TokenMatchesExample
*Zero or moreab* matches a, abbb
+One or more\d+
?Zero or one (optional)colou?r
{3}Exactly three\d{3}
{2,}Two or more
{2,5}Between two and five
+? *? {n,m}?Lazy - match as few as possible<.+?> stops at the first >

Greedy vs lazy: <.+> against <a><b> matches the whole string, because + takes as much as it can. <.+?> matches just <a>. This single character causes more regex bugs than anything else.

Groups & alternation

TokenMatchesExample
(abc)Capturing group - available as $1(\d{4})-(\d{2})
(?:abc)Non-capturing group - groups without numberingUse it when you only need the grouping
(?<year>\d{4})Named groupRead it back as groups.year
a|bEither a or b(jpg|png|gif)
\1Backreference to group 1(\w)\1 finds a doubled letter

Lookaround

TokenMatchesExample
(?=abc)Lookahead - followed by, without consuming\d+(?= USD) takes the number before " USD"
(?!abc)Negative lookahead - not followed by^(?!test) excludes lines starting with test
(?<=abc)Lookbehind - preceded by(?<=\$)\d+ takes the number after a $
(?<!abc)Negative lookbehind

Flags

g global

Find every match, not just the first. Required for replace-all and for iterating matches.

i ignore case

/abc/i matches ABC.

m multiline

Makes ^ and $ match at each line break instead of only at the ends of the string.

s dotAll

Lets . match newlines too - essential when matching across lines.

u unicode

Enables \p{...} property escapes and correct handling of astral characters like emoji.

y sticky

Match only at lastIndex - used by tokenizers.

Ready-made patterns

Pragmatic, not RFC-perfect. Paste any of these into the regex tester to try them.

GoalPatternNote
Email (practical)^[^\s@]+@[^\s@]+\.[^\s@]{2,}$Do not try to fully validate email with regex - send a confirmation instead.
UUID v4^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$The 4 and [89ab] pin the version and variant.
IPv4^((25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(25[0-5]|2[0-4]\d|1?\d?\d)$Rejects 999.1.1.1, unlike \d{1,3}.
ISO date^\d{4}-\d{2}-\d{2}$Shape only - it still allows 2026-13-45.
Hex colour^#(?:[0-9a-f]{3}|[0-9a-f]{6})$With the i flag.
URL slug^[a-z0-9]+(?:-[a-z0-9]+)*$No leading, trailing or doubled hyphens.
Trim whitespace^\s+|\s+$Replace with the empty string, g flag.
Leading zeros^0+(?=\d)Strips zeros but keeps a lone 0.
Duplicate word\b(\w+)\s+\1\bFinds "the the".

Traps that bite in production

Catastrophic backtracking

Nested quantifiers like (a+)+$ can take exponential time on a non-matching input, hanging the thread. This is a real denial-of-service vector (ReDoS) whenever the pattern or the input comes from a user.

. stops at newlines

By default . never crosses a line break, so multi-line matches silently fail. Add the s flag.

Unescaped dots

file.txt as a pattern also matches fileXtxt. Escape it: file\.txt.

Emoji are two code units

Without the u flag, . matches half an emoji and produces broken output. See the test-string library.

Anchors with m

Forgetting m when validating multi-line input means ^ only matches once, at the very start.

Do not parse HTML

HTML is not a regular language; nesting defeats any pattern. Use a parser.

Try a pattern now

Open the regex tester Test strings →

More from Learning

Guides and references for test data, file handling and AI evals. All free, no sign-up. See the full hub.

Synthetic data for AI evalsWhat you can download, what you buildRAG test corpusDocuments with extraction trapsJSONL for evalsThe format, and ten ways it breaksMock API for agentsRecords, pagination, failures on demandSafe test dataReserved domains, IPs, numbers & cardsSynthetic PIIFake people that reach nobodyTest card numbersEvery brand, declines, 3D SecureTest phone numbersReserved US, UK and Australian rangesReserved IP addressesDocumentation ranges and SSRF casesExample domains.test, .invalid, example.com, and trapsQA test stringsUnicode, emoji, injection & edge casesFilename compatibilityWhat breaks across Windows, Mac & LinuxFile systemsPOSIX, NTFS, APFS, ext4, SMB, NFS, NASFile signaturesMagic numbers that identify every formatCharacter encodingsUTF-8, UTF-16, BOM & normalizationUpload validationThe checklist, with a file for each checkMIME typesThe right Content-Type for every extensionHTTP status codesEvery code and when you actually see itDates & timesISO 8601, epoch, Excel serials, DSTHTTP headersContent-Type, Disposition, Range, CORSGenerate files (CLI)Make test files on any OSCrypto & certificatesSSL/PEM, hashing, encryptionWeb app testingWhat to test, with a file for each caseDesktop app testingPaths, names, encodings and savingMobile app testingPickers, photos, flaky networksCLI testingArguments, pipes and exit codesLarge file upload testingDefault limits, 413s and exact sizes1 GB test file1 GB and 2 GB, with SHA-25610 GB test fileMake one locally in secondsDownload speed test files10 MB to 2 GB of random data