πŸ” Regex Cheat Sheet

Every regular-expression pattern you actually use, in one page. Open the matching regex tester in another tab and paste along as you read.

Updated October 2026 Β· covers JavaScript (ES2024), PCRE / PCRE2, Python 3.13, Go, and .NET notable differences.

Contents

βš“ Anchors & boundaries

PatternMatchesExample
^Start of string (or start of line with m flag)^Hello
$End of string (or end of line with m flag)world$
\bWord boundary\bcat\b
\BNon-word boundary\Bing\b (match "ing" inside a word)
\AStart of input (PCRE/Python; not JS)\Afoo
\zAbsolute end of input (PCRE/Python; not JS)bar\z
\ZEnd of input, before trailing newline (PCRE/Python)bar\Z

πŸ”€ Character classes

PatternMatchesExample
.Any character except newline (any including newline with s flag)a.c β†’ "abc", "a7c"
[abc]Any one of a, b, c[aeiou]
[^abc]Any character NOT a, b, c[^0-9]
[a-z]Range: any lowercase letter[A-Za-z0-9_]
\dDigit (equivalent to [0-9])\d{3}-\d{4}
\DNon-digit\D+
\wWord char ([A-Za-z0-9_]; broader with Unicode flag)\w+
\WNon-word char\W+
\sWhitespace (space, tab, newline, etc)\s+
\SNon-whitespace\S+
[[:alpha:]]POSIX class (PCRE, not JS). Also: alnum, digit, space, upper, lower, punct, xdigit[[:alnum:]]+
Watch out: inside a character class, most metacharacters lose their meaning. [.] matches a literal dot. But -, ], ^, and \ still need care.

πŸ”’ Quantifiers

PatternMatchesExample
*0 or more (greedy)a* β†’ "", "a", "aaa"
+1 or morea+ β†’ "a", "aaa"
?0 or 1 (optional)colou?r β†’ "color", "colour"
{n}Exactly n\d{4} β†’ "2026"
{n,}n or more\w{3,}
{n,m}Between n and m (inclusive)\d{2,4}
*?0 or more, non-greedy (lazy)<.*?> stops at first >
+?1 or more, non-greedy".+?"
??0 or 1, non-greedya??
*+ / ++ / ?+Possessive (PCRE/Java; not JS). No backtracking.a++b
Greedy vs lazy: <.*> on "<a><b>" matches "<a><b>". <.*?> matches just "<a>". Lazy is usually what you want for HTML-like data.

πŸ‘₯ Groups & backreferences

PatternMeaningExample
(abc)Capturing group β€” remembered as $1 / \1(\w+)\s+\1 β†’ repeated word
(?:abc)Non-capturing group β€” groups but doesn't remember(?:foo|bar)+
(?<name>abc)Named capturing group(?<year>\d{4})
\1 \2 \3Backreference to group by number(['"])(.*?)\1
\k<name>Backreference to named group(?<q>["']).*?\k<q>
a|bAlternation (OR)cat|dog|bird
(?>abc)Atomic group β€” no backtracking into it (PCRE/.NET/Java)(?>\d+)x

In the replacement string, use $1, $2, $<name> (JS, PCRE). Python uses \1 / \g<name>.

πŸ”­ Lookaround (zero-width)

Lookaround asserts that something is or isn't next to the match without consuming it.

PatternNameExample
(?=abc)Positive lookahead\d+(?=px) β†’ digits before "px"
(?!abc)Negative lookahead\d+(?!px)
(?<=abc)Positive lookbehind(?<=\$)\d+ β†’ "100" in "$100"
(?<!abc)Negative lookbehind(?<!un)happy
JS note: variable-length lookbehind only works in Chrome, Node β‰₯10, Safari 16.4+. Fixed-length is fine everywhere. Go's RE2 does not support lookaround at all.

🚩 Flags & modifiers

FlagNameEffect
iCase-insensitive/HELLO/i matches "hello"
gGlobal (JS)Find all matches, not just the first
mMultiline^ and $ match per-line
sDotall / single-line. also matches newline
uUnicode (JS)Treats input as Unicode code points; enables \p{...}
vUnicode v-mode (JS, 2024)Set operations in []; \p{...} for strings
ySticky (JS)Match only at lastIndex
xExtended (PCRE/Python)Whitespace in pattern is ignored; # starts comments
dHas-indices (JS)Result includes indices array for each capture

In-pattern flag setting: (?i)foo turns on i for the rest; (?i)foo(?-i)bar turns it on then off (PCRE / Python / .NET; not JS).

πŸ›‘οΈ Escapes & special characters

PatternMatches
\nNewline (LF, 0x0A)
\rCarriage return (CR, 0x0D)
\tTab
\0Null byte
\xFFHex byte (2 digits)
ΓΏUnicode code point (4 hex digits; JS, Java)
\u{1F600}Unicode code point by number (JS u/v, PCRE)
\\Literal backslash
\.Literal dot

Metacharacters needing escape outside character classes: . * + ? ( ) [ ] { } ^ $ | \ /.

🌐 Unicode (JS u/v flag, PCRE, Python)

PatternMeaningExample
\p{L}Any letter (any language)\p{L}+
\p{N}Any numeric character\p{N}+
\p{M}Combining marka\p{M}*
\p{P}Punctuation\p{P}+
\p{Z}Separator (space-like)
\p{S}Symbol
\p{Cc}Control char
\p{Cf}Format char (invisible)useful for finding invisible-unicode injections
\p{Script=Greek}Letters from a specific script\p{Script=Hiragana}+
\P{L}Negated β€” any NON-letter

With JS's v flag (2024), \p{RGI_Emoji} matches full emoji sequences including skin tone + ZWJ joiners β€” much easier than before.

πŸ§ͺ 25+ copy-paste recipes

Each pattern is tested against JS. Where PCRE / Python differs it's noted. Click regex tester to try one.

Emails, URLs, identifiers

Email (practical, not RFC-strict)
^[^\s@]+@[^\s@]+\.[^\s@]+$
90% of real emails. Perfect RFC validation is impossible with regex β€” use a verification email.
URL (http / https)
^https?:\/\/[^\s/$.?#].[^\s]*$
Use new URL(str) in JS for a real validator; this is for quick extraction.
UUID v4
^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
For any version drop the 4 and [89ab] constraints.
Hex color
^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$
Covers 3-digit shorthand, 6-digit, and 8-digit (with alpha).
Slug (URL-safe)
^[a-z0-9]+(?:-[a-z0-9]+)*$
Lowercase, digits, single hyphens between words.

Networking

IPv4
^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$
Rejects 999.0.0.1.
IPv6 (lenient)
^(?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$
Doesn't accept :: shorthand. For full compliance use net.ParseIP / ipaddress module.
MAC address
^(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}$
Supports both 00:11:... and 00-11-....
Hostname / FQDN
^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$
Max 253 chars, labels ≀ 63.

Dates & times

ISO 8601 date (YYYY-MM-DD)
^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$
Rejects month 13, day 32. Doesn't check Feb 30.
ISO 8601 datetime
^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})$
Covers 2026-10-05T14:30:00Z and 2026-10-05T14:30:00+02:00.
24-hour time (HH:MM)
^(?:[01]\d|2[0-3]):[0-5]\d$
12-hour time with am/pm
^(?:0?[1-9]|1[0-2]):[0-5]\d\s?[ap]m$
Case-insensitive flag recommended.

Numbers

Integer (signed)
^-?\d+$
Decimal / float
^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$
Positive integer only
^[1-9]\d*$
Currency USD (with commas)
^\$?\d{1,3}(?:,\d{3})*(?:\.\d{2})?$

Credit cards & IDs

Visa
^4\d{12}(?:\d{3})?$
Mastercard
^(?:5[1-5]\d{2}|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)\d{12}$
AmEx
^3[47]\d{13}$
US SSN (format only)
^(?!000|666|9\d\d)\d{3}-(?!00)\d{2}-(?!0000)\d{4}$
Rejects impossible ranges. Doesn't verify issuance.

Strings & text

Non-empty, trimmed
^\S(?:.*\S)?$
Password: 8+ chars, upper, lower, digit, symbol
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$
Four lookaheads. Please also allow passphrases.
Duplicated whitespace
\s{2,}
Replace with single space to normalize.
Trim leading/trailing whitespace
^\s+|\s+$
With g flag, replace with empty string.
Invisible-Unicode detection
[​-‏
- ⁠-]
Zero-width spaces, bidi overrides, BOM. See our invisible-unicode attack guide.

Code / markup

HTML tag (lazy, naive)
<([a-z][a-z0-9]*)\b[^>]*>.*?</\1>
For anything beyond toy use, parse HTML; don't regex it.
Markdown link
\[([^\]]+)\]\(([^)]+)\)
$1 = label, $2 = URL.
JS single-line comment
\/\/.*$
Multiline flag recommended.
JS multi-line comment
\/\*[\s\S]*?\*\/
[\s\S] dodges the dot-doesn't-match-newline issue without s flag.

πŸ—£οΈ Dialect differences (JS / PCRE / Python / Go)

FeatureJSPCREPythonGo (RE2)
Variable-length lookbehindβœ… (2022+)⚠️ bounded⚠️ bounded❌
Lookaround at allβœ…βœ…βœ…βŒ
Named groupsβœ… (?<n>)βœ… (?P<n>) / (?<n>)βœ… (?P<n>)βœ… (?P<n>)
Backreferencesβœ…βœ…βœ…βŒ
Possessive quantifiersβŒβœ…βœ… (3.11+)❌
Recursion / subroutinesβŒβœ…βŒβŒ
POSIX classes [[:alpha:]]βŒβœ…βŒβŒ
Catastrophic backtracking possibleβš οΈβš οΈβš οΈβœ… linear-time

Go's RE2 trades features for guaranteed linear time β€” no catastrophic backtracking ever. For user-supplied patterns in a server, that's a big deal.

⚠️ Gotchas & performance

Catastrophic backtracking

Patterns with nested quantifiers and overlap can blow up. The classic: ^(a+)+$ on aaaaaaaaaaaaaaaab takes exponential time. Fixes:

Dot doesn't match newline (unless s)

If you need "any character including newline", use [\s\S] as a portable workaround.

Anchors in multiline mode

With m, ^/$ match per-line. Use \A/\z (PCRE/Python) for absolute start/end β€” not in JS.

Unicode without the flag

In JS, /./ on an emoji returns two chars (surrogate pair). Use the u flag to get one. The v flag is even better for emoji sequences.

Replace-all

In JS pre-ES2021, use str.replace(/foo/g, 'bar'). In ES2021+, str.replaceAll('foo', 'bar') for literal strings or str.replaceAll(/foo/g, 'bar') (the g flag is still required).

🧰 Related tools on this site