Regex Cheat Sheet — Every Token With Examples

Every regular expression token with a working example, support in JavaScript, PCRE/PHP, Python, Go, Java and .NET, and a Try it link that opens the regex tester pre-filled.

Last verified: 2026-10-18 against ECMAScript 2025 (MDN), PCRE2 10.45, Python 3.14 re, Go 1.27 regexp/syntax, Java 25 Pattern and the .NET regex reference. Sources: MDN regular expressions, PCRE2 pattern syntax, Python re, Go regexp/syntax, Java Pattern, .NET regex quick reference.

82 entries
Regex flavour

✓ same syntax · ~ different syntax or limited · ✗ not supported. Examples run in JavaScript; the notes give the syntax for other languages.

Characters and escapes

Most characters match themselves. These twelve have a special meaning and need a backslash to be matched literally: \ ^ $ . | ? * + ( ) [ { (and ] } in some positions).

.Any character#

Any single character except a line break. Add the s (dotAll) flag to include line breaks.

/h.t/g on “hat hot h t hit h↵t” matches “hat” “hot” “h t” “hit”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • Python re: Excludes only \n; JavaScript also excludes \r, \u2028 and \u2029.
  • Go RE2: Excludes only \n.
\. \$ \(Escape a metacharacter#

A backslash makes the next special character literal: \. is a real dot, \$ a dollar sign.

/\$\d+\.\d{2}/g on “Total $45.00, tax $3.15, tip 5” matches “$45.00” “$3.15”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
\t \n \rTab, newline, carriage return#

Control characters by name. Windows line endings are \r\n; \r?\n matches both styles.

/\w+\t\w+/g on “name⇥age↵ana⇥31” matches “name⇥age” “ana⇥31”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
\xhhCharacter by hex code#

Exactly two hex digits: \x41 is A, \x20 a space.

/\x41/g on “A b A” matches “A” “A”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
\uhhhhCharacter by Unicode code unit#

Four hex digits for a character in the Basic Multilingual Plane: \u00e9 is é.

/\u00e9/g on “café résumé” matches “é” “é” “é”
✓ JS Supported✗ PCRE Not supported✓ Py Supported✗ Go Not supported✓ Java Supported✓ .NET Supported
  • PCRE / PHP: Use \x{e9}.
  • Go RE2: Use \x{e9}.
\u{1F600}Any code point (astral too)#

Braced code point, needed for emoji and other characters above U+FFFF. JavaScript requires the u or v flag.

/\u{1F600}/gu on “Hi 😀 there 😀” matches “😀” “😀”
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited~ Go Different syntax / limited~ Java Different syntax / limited✗ .NET Not supported
  • PCRE / PHP: Write \x{1F600} (PHP needs the u modifier).
  • Python re: Write \U0001F600 (eight hex digits).
  • Go RE2: Write \x{1F600}.
  • Java: Write \x{1F600}.
  • .NET: Only \uhhhh; an emoji is two UTF-16 code units, e.g. 😀.

Character classes

A class matches exactly one character from a set. Inside [ ], most metacharacters lose their meaning; only ] \ ^ and - need care.

[abc]Any one of#

One character from the list.

/gr[ae]y/g on “gray grey groy” matches “gray” “grey”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
[^abc]None of#

One character that is not in the list (a ^ anywhere but first is literal). Matches line breaks too.

/[^aeiou\s]/g on “regex” matches “r” “g” “x”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
[a-z]Range#

Characters between two code points. Combine ranges: [A-Fa-f0-9] is a hex digit. A - first or last is literal.

/[A-Fa-f0-9]+/g on “x: 3fA9 zz” matches “3fA9”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
\d \DDigit / non-digit#

\d is a digit, \D anything else.

/\d+/g on “Order 66, room 101” matches “66” “101”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • Python re: In str patterns \d matches any Unicode digit (e.g. ٣); use re.ASCII for 0-9 only.
  • .NET: Matches any Unicode digit unless RegexOptions.ECMAScript is set.
\w \WWord character / non-word#

Letters, digits and underscore. In JavaScript and Go that means ASCII only: \w does not match é.

/\w+/g on “snake_case and kebab-case” matches “snake_case” “and” “kebab” “case”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • PCRE / PHP: ASCII unless PCRE2_UCP (PHP: u modifier plus (*UCP)).
  • Python re: Unicode letters and digits by default in str patterns.
  • Java: ASCII unless the U flag (UNICODE_CHARACTER_CLASS) is on.
  • .NET: Unicode letters, digits and connector punctuation.
\s \SWhitespace / non-whitespace#

Space, tab, line breaks and (in most engines) other Unicode spaces.

/\s+/g on “a b⇥c” matches “ ” “⇥”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • Go RE2: ASCII whitespace only: \t \n \f \r and space.
[[:alpha:]]POSIX bracket class#

Named classes such as [:alpha:], [:digit:], [:space:], [:punct:], used inside brackets.

Syntax (not in JavaScript): [[:alpha:]]+
✗ JS Not supported✓ PCRE Supported✗ Py Not supported✓ Go Supported~ Java Different syntax / limited✗ .NET Not supported
  • JavaScript: Use [A-Za-z] or \p{L} with the u flag.
  • Java: Use \p{Alpha}, \p{Digit}, \p{Punct}.
[\p{L}--[a-z]]Class subtraction / intersection#

Set operations inside a class. JavaScript needs the v flag (ES2024): -- subtracts, && intersects.

/[\p{L}--[a-z]]+/gv on “abcÉtéXYZ” matches “É” “éXYZ”
✓ JS Supported~ PCRE Different syntax / limited✗ Py Not supported✗ Go Not supported~ Java Different syntax / limited~ .NET Different syntax / limited
  • PCRE / PHP: PCRE2 10.45+ only, with the (?[ … ]) extended-class syntax.
  • Java: Intersection [a-z&&[^aeiou]]; subtraction is written as intersection with a negation.
  • .NET: Subtraction [a-z-[aeiou]]; no intersection.

Anchors and boundaries

Anchors match a position, not a character, so they never consume text.

^ $Start / end of string (or line with m)#

Without the m flag, ^ and $ are the start and end of the whole input; with it, of each line.

/^\w+/gm on “first line↵second line” matches “first” “second”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • PCRE / PHP: $ also matches before a final \n.
  • Python re: $ also matches before a final \n.
  • Java: $ also matches before a final line terminator.
  • .NET: $ also matches before a final \n.
\bWord boundary#

Between a word character and a non-word character (or the edge of the input). Use it to match whole words.

/\bcat\b/g on “cat concat cats cat.” matches “cat” “cat”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • JavaScript: ASCII word characters only, even with the u flag.
  • Go RE2: ASCII word characters only.
\BNot a word boundary#

Inside a word, e.g. "cat" only when it is part of a longer word.

/\Bcat/g on “concat cat bobcat” matches “cat” “cat”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
\A \z \ZAbsolute start / end#

Start and end of the input regardless of multiline mode. \Z also allows a final newline (except in Python, where it is a synonym for \z).

Syntax (not in JavaScript): \A\d+\z
✗ JS Not supported✓ PCRE Supported~ Py Different syntax / limited~ Go Different syntax / limited✓ Java Supported✓ .NET Supported
  • JavaScript: Use ^ and $ without the m flag.
  • Python re: \A and \z (3.14+); \Z means absolute end, like \z elsewhere.
  • Go RE2: \A and \z; no \Z.
\GEnd of previous match#

Position where the last match ended; used to match contiguous runs.

Syntax (not in JavaScript): \G\d
~ JS Different syntax / limited✓ PCRE Supported✗ Py Not supported✗ Go Not supported✓ Java Supported✓ .NET Supported
  • JavaScript: No \G; the y (sticky) flag gives the same "start exactly here" behaviour.

Quantifiers: greedy, lazy, possessive

A quantifier repeats the item before it. Greedy (default) takes as much as possible then backs off; lazy (add ?) takes as little as possible; possessive (add +) never backs off.

*Zero or more#

Repeat 0 to unlimited times.

/ba*/g on “b ba baaa” matches “b” “ba” “baaa”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
+One or more#

Repeat 1 to unlimited times.

/lo+l/g on “lol loool ll” matches “lol” “loool”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
?Optional#

Zero or one time.

/colou?r/g on “color colour colouur” matches “color” “colour”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
{n}Exactly n#

Exactly n repetitions.

/\d{3}/g on “12 345 6789” matches “345” “678”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
{n,}n or more#

At least n repetitions.

/\d{2,}/g on “1 22 333” matches “22” “333”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
{n,m}Between n and m#

From n to m repetitions, as many as possible.

/\d{2,3}/g on “1 22 4444” matches “22” “444”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • Go RE2: Counts above 1000 are rejected.
{,m}Up to m#

Zero to m repetitions. Only some engines accept it; elsewhere it is a literal "{,m}" or an error. {0,m} works everywhere.

Syntax (not in JavaScript): \d{,3}
✗ JS Not supported~ PCRE Different syntax / limited✓ Py Supported✗ Go Not supported✗ Java Not supported✗ .NET Not supported
  • JavaScript: Literal text without u, a syntax error with u; write {0,3}.
  • PCRE / PHP: PCRE2 10.43+ only.
  • Go RE2: Write {0,3}.
  • Java: Write {0,3}.
  • .NET: Treated as literal text; write {0,3}.
.* .+Greedy (default)#

Takes the longest possible match, then gives back characters until the rest fits. Here it swallows both tags.

/<.+>/g on “<b>bold</b>” matches “<b>bold</b>”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
*? +? ?? {n,m}?Lazy (non-greedy)#

Takes the shortest possible match. Usually the fix when a pattern "matches too much".

/<.+?>/g on “<b>bold</b>” matches “<b>” “</b>”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • Go RE2: Also available as the U flag, which swaps greedy and lazy.
*+ ++ ?+Possessive#

Greedy with no backtracking: once matched, characters are never given back. Faster failure, and a defence against catastrophic backtracking.

Syntax (not in JavaScript): "[^"]*+"
✗ JS Not supported✓ PCRE Supported~ Py Different syntax / limited✗ Go Not supported✓ Java Supported✗ .NET Not supported
  • JavaScript: No possessive quantifiers or atomic groups; emulate with (?=(…))\1.
  • Python re: Python 3.11+.
  • Go RE2: Not needed: RE2 never backtracks.
  • .NET: Use an atomic group (?>…).

Groups and backreferences

Parentheses group items for quantifiers and alternation, and (unless marked non-capturing) save what they matched.

( … )Capturing group#

Groups and captures; numbered from 1 by opening parenthesis.

/(\d{3})-(\d{4})/g on “Call 555-0199 or 555-0123” matches “555-0199” “555-0123”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
(?: … )Non-capturing group#

Groups without saving, so group numbers stay stable and matching is a little cheaper.

/(?:ab)+/g on “ababab ab a” matches “ababab” “ab”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
(?<name> … )Named group#

Captures under a name you can read back (match.groups.name in JavaScript).

/(?<year>\d{4})-(?<month>\d{2})/g on “Released 2026-10” matches “2026-10”
✓ JS Supported✓ PCRE Supported~ Py Different syntax / limited✓ Go Supported✓ Java Supported✓ .NET Supported
  • PCRE / PHP: Also (?'name'…) and (?P<name>…).
  • Python re: Only (?P<name>…).
  • Go RE2: (?P<name>…); (?<name>…) also accepted since Go 1.22.
  • .NET: Also (?'name'…).
\1Backreference by number#

Matches the same text a group captured earlier.

/(\w)\1/g on “bookkeeper” matches “oo” “kk” “ee”
✓ JS Supported✓ PCRE Supported✓ Py Supported✗ Go Not supported✓ Java Supported✓ .NET Supported
  • Go RE2: RE2 has no backreferences (they would break its linear-time guarantee).
\k<name>Backreference by name#

Same as \1 but by name. The example matches text in matching quotes.

/(?<q>['"]).*?\k<q>/g on “say "hi" or 'yo'” matches “"hi"” “'yo'”
✓ JS Supported✓ PCRE Supported~ Py Different syntax / limited✗ Go Not supported✓ Java Supported✓ .NET Supported
  • PCRE / PHP: Also \k{name}, \g{name} and (?P=name).
  • Python re: Write (?P=name).
a|bAlternation (or)#

Either side. Alternatives are tried left to right, so put longer ones first when one is a prefix of another.

/cat|dog/g on “hotdog catalog” matches “dog” “cat”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
(?> … )Atomic group#

Once the group has matched, the engine will not backtrack into it.

Syntax (not in JavaScript): (?>a|ab)c
✗ JS Not supported✓ PCRE Supported~ Py Different syntax / limited✗ Go Not supported✓ Java Supported✓ .NET Supported
  • Python re: Python 3.11+.
  • Go RE2: Not needed: RE2 never backtracks.
(?i) (?i: … )Inline flags#

Turn flags on or off inside the pattern. (?i) applies to the rest of the pattern; (?i:…) only to the group; (?-i:…) turns a flag off.

/(?i:hello) world/g on “HELLO world HELLO WORLD” matches “HELLO world”
~ JS Different syntax / limited✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • JavaScript: Only the scoped (?i:…) / (?-i:…) form, for i, m and s (ES2025). (?i) at the start is a syntax error.
  • Python re: Global (?i) must be at the very start of the pattern (an error elsewhere since 3.11); (?i:…) works anywhere.
(?(1)yes|no)Conditional#

Matches "yes" if group 1 participated, otherwise "no".

Syntax (not in JavaScript): (<)?\w+(?(1)>)
✗ JS Not supported✓ PCRE Supported✓ Py Supported✗ Go Not supported✗ Java Not supported✓ .NET Supported
(?R) (?1)Recursion / subroutine#

Re-enters the whole pattern or a group, for nested structures such as balanced parentheses.

Syntax (not in JavaScript): \((?:[^()]|(?R))*\)
✗ JS Not supported✓ PCRE Supported✗ Py Not supported✗ Go Not supported✗ Java Not supported~ .NET Different syntax / limited
  • Python re: Available in the third-party regex module.
  • .NET: No recursion; balancing groups (?<open-close>…) handle nesting.
(?# … )Inline comment#

Ignored by the engine. For longer comments use the x (extended) flag.

Syntax (not in JavaScript): \d{3}(?#area code)
✗ JS Not supported✓ PCRE Supported✓ Py Supported✗ Go Not supported✗ Java Not supported✓ .NET Supported

Lookahead and lookbehind

Lookarounds check what is next to the current position without including it in the match. They are zero-width, like anchors.

(?= … )Positive lookahead#

Followed by … (not included in the match).

/\d+(?=px)/g on “10px 20em 30px” matches “10” “30”
✓ JS Supported✓ PCRE Supported✓ Py Supported✗ Go Not supported✓ Java Supported✓ .NET Supported
  • Go RE2: RE2 has no lookaround of any kind.
(?! … )Negative lookahead#

Not followed by …. The \d inside stops the engine from giving back digits to make the check pass.

/\d+(?!px|\d)/g on “10px 20em” matches “20”
✓ JS Supported✓ PCRE Supported✓ Py Supported✗ Go Not supported✓ Java Supported✓ .NET Supported
(?<= … )Positive lookbehind#

Preceded by … (not included in the match).

/(?<=\$)\d+(?:\.\d\d)?/g on “Cost: $42.50 or 42” matches “42.50”
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited✗ Go Not supported~ Java Different syntax / limited✓ .NET Supported
  • JavaScript: Any length (ES2018).
  • PCRE / PHP: Each alternative must have a bounded length; variable length (max 255 by default) since PCRE2 10.43.
  • Python re: Fixed width only: (?<=ab|cd) is fine, (?<=a+) is an error.
  • Java: Bounded length only: no * or + inside.
  • .NET: Any length.
(?<! … )Negative lookbehind#

Not preceded by ….

/(?<!\$)\b\d+\b/g on “$30 and 45” matches “45”
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited✗ Go Not supported~ Java Different syntax / limited✓ .NET Supported
  • PCRE / PHP: Same length rules as positive lookbehind.
  • Python re: Fixed width only.
  • Java: Bounded length only.
\KReset match start#

Drops everything matched so far from the result; a lookbehind without length limits.

Syntax (not in JavaScript): price: \K\d+
✗ JS Not supported✓ PCRE Supported✗ Py Not supported✗ Go Not supported✗ Java Not supported✗ .NET Not supported
  • JavaScript: Use (?<=…) or a capture group.

Flags (modifiers)

JavaScript writes flags after the closing slash (/x/gi). Other languages pass constants (re.I, Pattern.CASE_INSENSITIVE, RegexOptions.IgnoreCase) or use inline (?i).

gGlobal (all matches)#

Find every match instead of stopping at the first. Required by matchAll and replaceAll.

/o/g on “foo boo” matches “o” “o” “o” “o”
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited~ Go Different syntax / limited~ Java Different syntax / limited~ .NET Different syntax / limited
  • PCRE / PHP: No flag: use preg_match_all() / preg_replace().
  • Python re: No flag: use re.findall(), re.finditer(), re.sub().
  • Go RE2: No flag: use the FindAll… methods.
  • Java: No flag: loop with matcher.find().
  • .NET: No flag: use Regex.Matches().
iIgnore case#

Case-insensitive matching.

/hello/gi on “Hello HELLO hello” matches “Hello” “HELLO” “hello”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • Python re: re.I / re.IGNORECASE or (?i).
  • Java: CASE_INSENSITIVE (ASCII unless UNICODE_CASE) or (?i).
  • .NET: RegexOptions.IgnoreCase or (?i).
mMultiline#

^ and $ match at line starts and ends, not just the ends of the input.

/^-\s.+$/gm on “- one↵- two↵three” matches “- one” “- two”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • Python re: re.M / re.MULTILINE.
  • .NET: RegexOptions.Multiline.
sDot matches newline#

Makes . match line breaks too. Without it, [\s\S] is the portable "anything".

/<p>.*?</p>/gs on “<p>a↵b</p>” matches “<p>a↵b</p>”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • Python re: re.S / re.DOTALL.
  • Java: Pattern.DOTALL.
  • .NET: Called RegexOptions.Singleline.
xExtended (free spacing)#

Whitespace in the pattern is ignored and # starts a comment, so long patterns can be laid out over lines.

Syntax (not in JavaScript): (?x) \d{3} - \d{4} # local number
✗ JS Not supported✓ PCRE Supported✓ Py Supported✗ Go Not supported✓ Java Supported✓ .NET Supported
  • Python re: re.X / re.VERBOSE.
  • Java: Pattern.COMMENTS.
  • .NET: RegexOptions.IgnorePatternWhitespace.
uUnicode#

Treats the input as code points (so . matches a whole emoji), enables \p{…} and \u{…}, and makes invalid escapes errors.

/^.$/gu on “😀” matches “😀”
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited~ Go Different syntax / limited~ Java Different syntax / limited~ .NET Different syntax / limited
  • PCRE / PHP: PHP u modifier (UTF-8 mode); add (*UCP) for Unicode \w and \d.
  • Python re: No flag needed: str patterns are Unicode; re.ASCII opts out.
  • Go RE2: No flag: Go always works on UTF-8 code points.
  • Java: UNICODE_CASE and UNICODE_CHARACTER_CLASS (U).
  • .NET: No flag: always UTF-16 code units (an emoji is two).
vUnicode sets#

ES2024 upgrade of u: class set operations (--, &&), nested classes and string properties such as \p{RGI_Emoji}. Cannot be combined with u.

/[\p{L}&&\p{ASCII}]+/gv on “Ünïcode text” matches “n” “code” “text”
✓ JS Supported✗ PCRE Not supported✗ Py Not supported✗ Go Not supported✗ Java Not supported✗ .NET Not supported
ySticky#

Each match must start exactly where the previous one ended (lastIndex). Useful for tokenizers.

/\d/gy on “12a3” matches “1” “2”
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited✗ Go Not supported~ Java Different syntax / limited~ .NET Different syntax / limited
  • PCRE / PHP: Use \G.
  • Python re: Use pattern.match(text, pos).
  • Java: Use \G or matcher.lookingAt().
  • .NET: Use \G.
dMatch indices#

Adds match.indices with the start and end of every capture group (ES2022).

Syntax (not in JavaScript): /(?<y>\d{4})/d
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited~ Go Different syntax / limited~ Java Different syntax / limited~ .NET Different syntax / limited
  • PCRE / PHP: Offsets always available (PREG_OFFSET_CAPTURE).
  • Python re: Always available: m.span(n).
  • Go RE2: Always available: FindStringSubmatchIndex.
  • Java: Always available: matcher.start(n) / end(n).
  • .NET: Always available: Group.Index / Length.

Unicode properties \p{…}

Property escapes match characters by Unicode category or script, which is the only reliable way to match "any letter" across languages. In JavaScript they need the u or v flag.

\p{L}Any letter#

Letters in every script: é, ß, 東, д.

/\p{L}+/gu on “naïve café 東京 123” matches “naïve” “café” “東京”
✓ JS Supported✓ PCRE Supported✗ Py Not supported✓ Go Supported✓ Java Supported✓ .NET Supported
  • PCRE / PHP: PHP needs the u modifier for UTF-8 input.
  • Python re: Use the third-party regex module, or [^\W\d_] for "letters".
\p{Lu} \p{Ll}Uppercase / lowercase letter#

General categories: Lu uppercase, Ll lowercase, N number, P punctuation, S symbol, Z separator.

/\p{Lu}/gu on “Élan Vital” matches “É” “V”
✓ JS Supported✓ PCRE Supported✗ Py Not supported✓ Go Supported✓ Java Supported✓ .NET Supported
\P{…}Not in property#

Capital P negates: \P{L} is anything that is not a letter.

/\P{L}+/gu on “abc-123” matches “-123”
✓ JS Supported✓ PCRE Supported✗ Py Not supported✓ Go Supported✓ Java Supported✓ .NET Supported
\pLOne-letter shorthand#

Single-letter categories without braces.

Syntax (not in JavaScript): \pL+
✗ JS Not supported✓ PCRE Supported✗ Py Not supported✓ Go Supported✓ Java Supported✗ .NET Not supported
  • JavaScript: Braces are required: \p{L}.
  • .NET: Braces are required: \p{L}.
\p{Script=Greek}Script#

Characters of one writing system. sc= is the short form; Script_Extensions (scx=) also includes characters shared between scripts.

/\p{Script=Greek}+/gu on “alpha α, beta β” matches “α” “β”
✓ JS Supported~ PCRE Different syntax / limited✗ Py Not supported~ Go Different syntax / limited✓ Java Supported✗ .NET Not supported
  • PCRE / PHP: \p{Greek}, \p{sc:Greek} or \p{scx:Greek}.
  • Go RE2: \p{Greek}.
  • Java: Write \p{script=Greek}, \p{sc=Greek} or \p{IsGreek}.
  • .NET: Only named blocks such as \p{IsGreek} (a code range, not the script).
\p{sc=Han}Chinese / Japanese kanji#

Han ideographs. For Japanese kana add \p{sc=Hiragana} and \p{sc=Katakana}.

/\p{sc=Han}+/gu on “Tokyo 東京 2026 中文” matches “東京” “中文”
✓ JS Supported~ PCRE Different syntax / limited✗ Py Not supported~ Go Different syntax / limited✓ Java Supported~ .NET Different syntax / limited
  • PCRE / PHP: \p{Han}.
  • Python re: Use a range such as [\u4e00-\u9fff] (covers the main block only).
  • Go RE2: \p{Han}.
  • Java: Also \p{IsHan}.
  • .NET: Blocks only, e.g. \p{IsCJKUnifiedIdeographs}.
\p{RGI_Emoji}Emoji (whole sequences)#

With the v flag, matches complete emoji including skin tones and family sequences. With u, \p{Extended_Pictographic} matches single pictographs only.

/\p{RGI_Emoji}/gv on “Go 👍🏽 team 👨‍👩‍👧!” matches “👍🏽” “👨‍👩‍👧”
✓ JS Supported~ PCRE Different syntax / limited✗ Py Not supported✗ Go Not supported~ Java Different syntax / limited✗ .NET Not supported
  • PCRE / PHP: Single code points via Boolean properties in recent PCRE2 (10.40+); no sequence property.
  • Java: \p{IsEmoji} matches single code points (Java 21+).
\XGrapheme cluster#

One user-perceived character, e.g. e + combining accent, or a flag emoji.

Syntax (not in JavaScript): \X
✗ JS Not supported✓ PCRE Supported✗ Py Not supported✗ Go Not supported✓ Java Supported✗ .NET Not supported
  • JavaScript: Use Intl.Segmenter for grapheme splitting.
  • Python re: Available in the regex module.

Substitution (replacement) syntax

What to type in the replacement string. This is where languages differ most, so the column for your language matters more than the JavaScript example.

$&Whole match#

Inserts the entire matched text.

/\d+/g on “3 apples, 12 pears” replace with “[$&]” → “[3] apples, [12] pears”
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited~ Go Different syntax / limited~ Java Different syntax / limited✓ .NET Supported
  • PCRE / PHP: $0 or \0 in preg_replace.
  • Python re: \g<0>.
  • Go RE2: ${0} or $0 (Expand / ReplaceAllString).
  • Java: $0.
  • .NET: Also $0.
$1Numbered group#

Inserts what group 1 captured. Swap two words:

/(\w+)\s(\w+)/g on “hello world” replace with “$2 $1” → “world hello”
✓ JS Supported✓ PCRE Supported~ Py Different syntax / limited✓ Go Supported✓ Java Supported✓ .NET Supported
  • PCRE / PHP: Also \1 and ${1}.
  • Python re: \1 or \g<1> (use a raw string r"\1").
  • Go RE2: Use ${1}x when a letter or digit follows, or Go reads $1x as a group named "1x".
$<name>Named group#

Inserts a named group. Reformat an ISO date as day/month/year:

/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/g on “2026-10-18” replace with “$<d>/$<m>/$<y>” → “18/10/2026”
✓ JS Supported✗ PCRE Not supported~ Py Different syntax / limited~ Go Different syntax / limited~ Java Different syntax / limited~ .NET Different syntax / limited
  • PCRE / PHP: preg_replace has no named references; use the group number or preg_replace_callback().
  • Python re: \g<name>.
  • Go RE2: ${name} (or $name).
  • Java: ${name}.
  • .NET: ${name}.
$$Literal dollar sign#

Escapes $ in the replacement.

/(\d+)/g on “Price: 20” replace with “$$$1” → “Price: $20”
✓ JS Supported~ PCRE Different syntax / limited~ Py Different syntax / limited✓ Go Supported~ Java Different syntax / limited✓ .NET Supported
  • PCRE / PHP: A $ not followed by a digit or { is already literal; write ${1} after it.
  • Python re: $ is not special; escape backslashes as \\.
  • Java: \$ (Matcher.quoteReplacement() escapes a whole string).
$` $'Text before / after the match#

Inserts the input before or after the match. Rarely needed, but occasionally handy.

/=/ on “key=value” replace with “ is set ($') and was ($`) ” → “key is set (value) and was (key) value”
✓ JS Supported✗ PCRE Not supported✗ Py Not supported✗ Go Not supported✗ Java Not supported✓ .NET Supported

Common recipes (with honest caveats)

Patterns people search for most, written to be readable and safe from catastrophic backtracking. Each says what it does not do.

Email (practical)Find email-like strings#

Local part, @, and a domain with at least one dot.

/[\w.+-]+@[\w-]+(?:\.[\w-]+)+/g on “Write to ana.lee+news@example.co.uk or bob@test.dev.” matches “ana.lee+news@example.co.uk” “bob@test.dev”

Caveat: Rejects valid but rare addresses (quoted local parts, non-ASCII domains) and accepts some invalid ones (a..b@x.y). No regex can tell you a mailbox exists: send a confirmation email.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
URLFind http(s) links in text#

Stops at whitespace, quotes and angle brackets, and drops trailing punctuation such as a full stop or comma.

/https?://[^\s<>"]*[^\s<>".,;:!?)]/g on “See https://example.com/a?b=1, or (http://test.dev/x).” matches “https://example.com/a?b=1” “http://test.dev/x”

Caveat: Good for linkifying text, not for validation. To check a URL, use the URL parser of your language (new URL() in JavaScript) and test its protocol and host.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
IPv4 addressFour octets 0–255#

Each octet limited to 0–255 without leading zeros.

/\b(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}\b/g on “10.0.0.1 256.1.1.1 192.168.1.254” matches “10.0.0.1” “192.168.1.254”

Caveat: Does not handle IPv6, CIDR suffixes or ports. For validation use an IP parser (Python ipaddress, Go net/netip, Node net.isIP).

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Date YYYY-MM-DDISO 8601 calendar date#

Month 01–12 and day 01–31.

/\b\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])\b/g on “2026-10-18, 2026-13-01, 2026-02-31” matches “2026-10-18” “2026-02-31”

Caveat: Shape only: 2026-02-31 passes. Parse the date with a date library to reject impossible days.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Date MM/DD/YYYYUS-style date#

One- or two-digit month and day, four-digit year.

/\b(?:0?[1-9]|1[0-2])/(?:0?[1-9]|[12]\d|3[01])/\d{4}\b/g on “Due 10/18/2026 or 1/5/2027, not 13/01/2026” matches “10/18/2026” “1/5/2027”

Caveat: 01/02/2026 is 2 January in the US and 1 February almost everywhere else; a regex cannot know which was meant.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Phone (North America)(416) 555-0199 and variants#

Ten digits with optional parentheses, spaces, dots or dashes.

/\(?\b\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g on “(416) 555-0199, 416.555.0199, 4165550199” matches “(416) 555-0199” “416.555.0199” “4165550199”

Caveat: North American numbers only. For international numbers use a library such as libphonenumber; store numbers in E.164 form (next row).

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Phone (E.164)International format +CC…#

A plus sign, a country code that does not start with 0, up to 15 digits in total.

/^\+[1-9]\d{1,14}$/gm on “+14165550199↵+447911123456↵0044791112” matches “+14165550199” “+447911123456”

Caveat: Checks the E.164 shape, not whether the number is assigned or the right length for its country.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Hex colour#rgb, #rgba, #rrggbb, #rrggbbaa#

The four lengths CSS accepts.

/#(?:[\da-fA-F]{8}|[\da-fA-F]{6}|[\da-fA-F]{3,4})\b/g on “#fff #244b3f #12345 #ff000080 #1234567” matches “#fff” “#244b3f” “#ff000080”

Caveat: Matches inside longer text such as URLs with #fragments too; anchor with ^…$ to validate a single value.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
URL sluglowercase-words-with-hyphens#

Lowercase letters and digits separated by single hyphens.

/^[a-z0-9]+(?:-[a-z0-9]+)*$/gm on “my-post-2026↵My Post↵-bad-↵good” matches “my-post-2026” “good”

Caveat: ASCII only. To create slugs from titles, use the URL slug generator rather than a regex.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Trim whitespaceLeading and trailing spaces#

Replace with an empty string. Without the m flag, ^ and $ are the ends of the whole text.

/^\s+|\s+$/g on “ padded text ” replace with “” → “padded text”

Caveat: Every modern language has a built-in trim() that is faster and clearer; use the regex only where you cannot call code (editors, config files).

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Collapse spacesRuns of spaces to one#

Replace two or more spaces or tabs with a single space.

/[ \t]{2,}/g on “too many ⇥ spaces” replace with “ ” → “too many spaces”
✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Duplicate wordsthe the, is is#

A word followed by itself. With i, "The the" is caught too.

/\b(\w+)\s+\1\b/gi on “This is is a test test of The the editor” matches “is is” “test test” “The the”

Caveat: Needs backreferences, so it does not work in Go. "had had" and "that that" are sometimes correct English.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Password rulesLowercase, uppercase, digit, 12+ characters#

Each lookahead checks one rule from the start; .{12,} sets the length.

/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{12,}$/gm on “short1A↵alllowercase123↵GoodPassword42” matches “GoodPassword42”

Caveat: NIST SP 800-63B advises against composition rules: require length and check against breached-password lists instead.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
UUID8-4-4-4-12 hex#

Versions 1–8 with the RFC 9562 variant bits.

/\b[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\b/gi on “id 3f2b8c1e-9d4a-4b7e-8f6a-1c2d3e4f5a6b and 00000000-0000-0000-0000-000000000000” matches “3f2b8c1e-9d4a-4b7e-8f6a-1c2d3e4f5a6b”

Caveat: Rejects the nil UUID (all zeros) and the max UUID (all f), which are valid special values.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported
Strip HTML tagsRemove <tags>#

Replace with an empty string to get rough plain text.

/<[^>]+>/g on “<p>Hello <b>world</b></p>” replace with “” → “Hello world”

Caveat: Breaks on > inside attributes, comments and scripts, and does not decode &amp; entities. Never use it to sanitise untrusted HTML; use DOMParser or a sanitiser such as DOMPurify.

✓ JS Supported✓ PCRE Supported✓ Py Supported✓ Go Supported✓ Java Supported✓ .NET Supported

A static reference: searching and filtering happen in your browser, and Try it links open our in-browser regex tester. Browse all free tools.

Found a problem, or something that could be better? We read every message and we fix things quickly.

This regex cheat sheet lists every regular expression token you are likely to need, from \d and \b to lookbehind, possessive quantifiers and \p{Script=Greek}, each with a short explanation and an example that shows exactly what it matches. Every example has a Try it link that opens our regex tester with the pattern, flags and sample text already filled in, so you can change it and watch the matches move.

Regex looks the same everywhere but is not. Lookbehind is unlimited in JavaScript and .NET, fixed-width in Python, bounded in Java and PCRE, and missing in Go. Python spells named groups (?P<name>…), PHP cannot use names in a replacement, and only some engines know \A, \K or (?R). The flavour picker shows each token's support in JavaScript, PCRE/PHP, Python, Go, Java and .NET, with the alternative syntax where one exists. The examples themselves run in JavaScript; for the other languages, read the notes and test in that language before you ship.

How to use

  1. Search for a token (\b, lookahead) or a task (email, trim, duplicate words), or jump to a section from the chips at the top.
  2. Pick your language in the flavour bar. Tokens it does not support are dimmed, and the note under each entry gives the syntax your language uses instead.
  3. Click Try it in the regex tester to run the example live, then edit the pattern or the text there.
  4. Use the # next to an entry to link straight to it, or Print / Save as PDF for a compact two-column copy.

Frequently asked questions

What is the difference between greedy and lazy quantifiers?

A greedy quantifier (*, +, {n,m}) takes as many characters as it can and then gives some back if the rest of the pattern fails; a lazy one (*?, +?, {n,m}?) takes as few as possible. On <b>bold</b>, <.+> matches the whole string while <.+?> matches <b> and </b> separately. Possessive quantifiers (*+, ++) are greedy and never give characters back; JavaScript, Go and .NET do not have them.

Which languages support lookbehind?

JavaScript (since ES2018) and .NET allow lookbehind of any length. Java requires a bounded maximum length, so no * or + inside. Python's re module accepts only fixed-width lookbehind. PCRE2 required each alternative to have a fixed length until 10.43, which added variable-length lookbehind up to a limit (255 characters by default). Go's RE2 engine has no lookahead or lookbehind at all.

How do I match any letter, including accented and non-Latin letters?

Use the Unicode property \p{L}. In JavaScript it needs the u or v flag (/\p{L}+/u); PCRE, Go, Java and .NET support it directly. [a-zA-Z] misses é, ß and every non-Latin script, and \w is ASCII-only in JavaScript and Go. Python's built-in re has no \p{…}; use the third-party regex module, or [^\W\d_], which in Python 3 matches Unicode letters.

How do I use a captured group in the replacement?

It depends on the language: $1 in JavaScript, Java, .NET, Go and PHP; \1 or \g<1> in Python. Named groups are $<name> in JavaScript, ${name} in Java, .NET and Go, and \g<name> in Python; PHP's preg_replace has no named form, so use the number. The whole match is $& in JavaScript and .NET, $0 in Java and PHP, and \g<0> in Python.

Why does my regex work in JavaScript but not in Python (or the other way round)?

The usual culprits: named groups ((?<name>) in JavaScript, (?P<name>) in Python), \p{…} properties (JavaScript yes, Python re no), lookbehind length (any in JavaScript, fixed in Python), inline flags ((?i) at the start works in Python but is an error in JavaScript, which only has the scoped (?i:…)), and \d or \w matching Unicode digits and letters in Python but only ASCII in JavaScript. Also remember Python string escaping: write patterns as raw strings, r"\d+".

Is it safe to validate email addresses with a regex?

Only as a shape check. A practical pattern such as [\w.+-]+@[\w-]+(?:\.[\w-]+)+ catches typos, but it rejects some valid addresses (quoted local parts, internationalised domains) and accepts some invalid ones. No pattern can tell you that a mailbox exists, so check the shape loosely and then send a confirmation email.

Writing patterns that work in more than one language

If a pattern must run in several engines (a shared validation rule, a config file read by services in different languages), stay inside the common subset. These behave the same in all six engines on this page:

• Literal characters, escapes such as \. and \$, and the classes [abc], [^abc] and [a-z].

• \d, \s and \w, as long as your input is ASCII (Python and .NET match Unicode digits and letters too).

• ^ and $, \b, alternation, capturing and non-capturing groups.

• Greedy and lazy quantifiers: *, +, ?, {n}, {n,m} and their ? forms.

Leave out lookaround (Go has none), backreferences (Go), possessive quantifiers and atomic groups (JavaScript, Go and .NET lack one or both), named groups (Python's syntax differs) and \p{…} (Python's re lacks it). When you need one of those, keep one copy of the pattern per language and test each.

Avoiding catastrophic backtracking

Backtracking engines (JavaScript, PCRE, Python, Java, .NET) can take exponential time on patterns where a quantified group can match the same text in many ways, such as (a+)+$ or (\w|\d)*x. On a long input that almost matches, the engine tries every split before failing, and a web server can hang on one request. This is the regular expression denial of service (ReDoS) problem.

The fixes are mechanical: avoid nesting quantifiers over the same characters; make alternatives mutually exclusive; prefer a negated class such as [^"]* to .*? when you know the delimiter; use possessive quantifiers or atomic groups where your engine has them; and cap input length before matching. .NET also offers RegexOptions.NonBacktracking and a match timeout, PCRE has match limits you can set, and Go's RE2 engine guarantees linear time by not supporting the features that need backtracking.

Escaping regex inside strings

Most regex bugs in real code are string-escaping bugs, not regex bugs. The backslash is special to both the language's string literal and the regex engine, so a pattern written as a normal string needs double backslashes.

• JavaScript: a literal /\d+/ needs one backslash; new RegExp("\\d+") needs two. String.raw`\d+` avoids the doubling.

• Python: always use raw strings, r"\d+"; otherwise "\b" is a backspace character, not a word boundary.

• Java and C#: "\\d+" in ordinary strings (Java text blocks process escapes too); C# verbatim strings, @"\d+", keep backslashes as typed.

• Go: backtick raw strings, `\d+`, are the norm with regexp.MustCompile.

• PHP: patterns include delimiters, '/\d+/', and single-quoted strings keep most backslashes as typed.

Related free tools

  • Regex Tester — Test a regular expression against sample text with live match highlighting, capture groups and replace preview. Free, in your browser.
  • Git Cheat Sheet — Git commands organised by what you want to do: undo the last commit, rename a branch, delete a remote branch. Modern switch/restore with classic equivalents and danger badges.
  • Markdown Cheat Sheet — Every Markdown element with source and rendered preview, extended syntax (tables, task lists, footnotes, math, Mermaid, alerts), a 9-platform compatibility table and a live playground.
  • Cron Expression Generator — Build a cron schedule from dropdowns or paste one, read it in plain English, and see the next 10 run times in your zone and UTC. Free, in your browser.
  • Diff Checker — Compare two versions of a text, code or JSON file and see exactly which lines, words and characters changed.