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.
| Pattern | Matches | Example |
|---|---|---|
| ^ | Start of string (or start of line with m flag) | ^Hello |
| $ | End of string (or end of line with m flag) | world$ |
| \b | Word boundary | \bcat\b |
| \B | Non-word boundary | \Bing\b (match "ing" inside a word) |
| \A | Start of input (PCRE/Python; not JS) | \Afoo |
| \z | Absolute end of input (PCRE/Python; not JS) | bar\z |
| \Z | End of input, before trailing newline (PCRE/Python) | bar\Z |
| Pattern | Matches | Example |
|---|---|---|
| . | 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_] |
| \d | Digit (equivalent to [0-9]) | \d{3}-\d{4} |
| \D | Non-digit | \D+ |
| \w | Word char ([A-Za-z0-9_]; broader with Unicode flag) | \w+ |
| \W | Non-word char | \W+ |
| \s | Whitespace (space, tab, newline, etc) | \s+ |
| \S | Non-whitespace | \S+ |
| [[:alpha:]] | POSIX class (PCRE, not JS). Also: alnum, digit, space, upper, lower, punct, xdigit | [[:alnum:]]+ |
[.] matches a literal dot. But -, ], ^, and \ still need care.| Pattern | Matches | Example |
|---|---|---|
| * | 0 or more (greedy) | a* β "", "a", "aaa" |
| + | 1 or more | a+ β "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-greedy | a?? |
| *+ / ++ / ?+ | Possessive (PCRE/Java; not JS). No backtracking. | a++b |
<.*> on "<a><b>" matches "<a><b>". <.*?> matches just "<a>". Lazy is usually what you want for HTML-like data.| Pattern | Meaning | Example |
|---|---|---|
| (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 \3 | Backreference to group by number | (['"])(.*?)\1 |
| \k<name> | Backreference to named group | (?<q>["']).*?\k<q> |
| a|b | Alternation (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 asserts that something is or isn't next to the match without consuming it.
| Pattern | Name | Example |
|---|---|---|
| (?=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 |
| Flag | Name | Effect |
|---|---|---|
| i | Case-insensitive | /HELLO/i matches "hello" |
| g | Global (JS) | Find all matches, not just the first |
| m | Multiline | ^ and $ match per-line |
| s | Dotall / single-line | . also matches newline |
| u | Unicode (JS) | Treats input as Unicode code points; enables \p{...} |
| v | Unicode v-mode (JS, 2024) | Set operations in []; \p{...} for strings |
| y | Sticky (JS) | Match only at lastIndex |
| x | Extended (PCRE/Python) | Whitespace in pattern is ignored; # starts comments |
| d | Has-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).
| Pattern | Matches |
|---|---|
| \n | Newline (LF, 0x0A) |
| \r | Carriage return (CR, 0x0D) |
| \t | Tab |
| \0 | Null byte |
| \xFF | Hex 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: . * + ? ( ) [ ] { } ^ $ | \ /.
u/v flag, PCRE, Python)| Pattern | Meaning | Example |
|---|---|---|
| \p{L} | Any letter (any language) | \p{L}+ |
| \p{N} | Any numeric character | \p{N}+ |
| \p{M} | Combining mark | a\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.
Each pattern is tested against JS. Where PCRE / Python differs it's noted. Click regex tester to try one.
^[^\s@]+@[^\s@]+\.[^\s@]+$^https?:\/\/[^\s/$.?#].[^\s]*$new URL(str) in JS for a real validator; this is for quick extraction.^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$4 and [89ab] constraints.^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$^[a-z0-9]+(?:-[a-z0-9]+)*$^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$^(?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$:: shorthand. For full compliance use net.ParseIP / ipaddress module.^(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}$00:11:... and 00-11-....^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})$2026-10-05T14:30:00Z and 2026-10-05T14:30:00+02:00.^(?:[01]\d|2[0-3]):[0-5]\d$^(?:0?[1-9]|1[0-2]):[0-5]\d\s?[ap]m$^-?\d+$^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$^[1-9]\d*$^\$?\d{1,3}(?:,\d{3})*(?:\.\d{2})?$^4\d{12}(?:\d{3})?$^(?:5[1-5]\d{2}|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)\d{12}$^3[47]\d{13}$^(?!000|666|9\d\d)\d{3}-(?!00)\d{2}-(?!0000)\d{4}$^\S(?:.*\S)?$^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$\s{2,}^\s+|\s+$g flag, replace with empty string.[β-ββ¨-β―β -β―ο»Ώ]<([a-z][a-z0-9]*)\b[^>]*>.*?</\1>\[([^\]]+)\]\(([^)]+)\)$1 = label, $2 = URL.\/\/.*$\/\*[\s\S]*?\*\/[\s\S] dodges the dot-doesn't-match-newline issue without s flag.| Feature | JS | PCRE | Python | Go (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.
Patterns with nested quantifiers and overlap can blow up. The classic: ^(a+)+$ on aaaaaaaaaaaaaaaab takes exponential time. Fixes:
^(a++)+$ β refuses to backtrack.^(?>a+)+$.^a+$ works fine.s)If you need "any character including newline", use [\s\S] as a portable workaround.
With m, ^/$ match per-line. Use \A/\z (PCRE/Python) for absolute start/end β not in JS.
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.
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).