Every regex special character in one place
Regular expressions build matching power out of a small set of metacharacters: characters that mean something other than themselves. This reference lists the anchors, quantifiers, character classes, groups and lookaround assertions that are common to the three most-used engines — PCRE, JavaScript and Python — with a plain-language meaning and a working example for each.
How it works
A regex engine reads your pattern left to right. Literal characters match
themselves; metacharacters change the matching rules. Quantifiers like *, +,
? and {n,m} repeat the preceding token. Anchors like ^ and $ match
positions rather than characters. Character classes [...] match any one
character from a set, and groups (...) capture or scope sub-patterns.
^\d{3}-\d{4}$ matches 123-4567
colou?r matches color and colour
(?<=£)\d+(?:\.\d{2})? matches the number after a £ sign
To match a metacharacter literally, escape it with a backslash: \. matches a
real dot, \( matches a real parenthesis.
Tips and gotchas
- Alternation
|has the lowest precedence — wrap it in a group, likegr(a|e)y, to limit its scope. - A caret means start-of-string outside a class but negation as the first
character inside one:
[^0-9]. - Make quantifiers lazy with a trailing
?when greedy matching swallows too much text. - Named groups differ: JavaScript and PCRE use
(?<name>...), Python uses(?P<name>...). The filter notes flag these engine differences.
Quick-reference: the most common metacharacters
| Token | Name | Matches | Example |
|---|---|---|---|
. | Dot | Any character except newline | a.c matches abc, a2c |
^ | Caret | Start of string (or line in multiline mode) | ^Hello |
$ | Dollar | End of string (or line) | world$ |
* | Star | Zero or more of preceding | ab* matches a, ab, abb |
+ | Plus | One or more of preceding | ab+ matches ab, abb |
? | Question mark | Zero or one of preceding | colou?r matches color and colour |
{n,m} | Quantifier | Between n and m of preceding | \d{2,4} matches 2–4 digits |
[...] | Character class | Any one character in the set | [aeiou] matches a vowel |
[^...] | Negated class | Any character NOT in the set | [^0-9] matches non-digit |
\d | Digit shorthand | A decimal digit [0-9] | \d{3} matches three digits |
\w | Word shorthand | [a-zA-Z0-9_] | \w+ matches a word |
\s | Space shorthand | Whitespace (space, tab, newline) | \s+ matches runs of space |
(...) | Group | Captures or scopes the sub-pattern | (ab)+ |
(?:...) | Non-capturing group | Scopes without capturing | (?:ab)+ |
(?=...) | Lookahead | Asserts what follows (zero-width) | foo(?=bar) |
(?!...) | Negative lookahead | Asserts what does NOT follow | foo(?!bar) |
(?<=...) | Lookbehind | Asserts what precedes (zero-width) | (?<=£)\d+ |
(?<!...) | Negative lookbehind | Asserts what does NOT precede | (?<!un)happy |
\b | Word boundary | Between \w and \W (zero-width) | \bcat\b matches whole word |
| | Alternation | Either left or right pattern | cat|dog |
Greedy vs. lazy quantifiers
By default all quantifiers are greedy: they match as much as possible, then backtrack. Add ? after any quantifier to make it lazy (match as little as possible):
Greedy: <.+> on "<a> and <b>" matches "<a> and <b>" (whole string)
Lazy: <.+?> on "<a> and <b>" matches "<a>" then "<b>" (two matches)
Lazy quantifiers are essential when extracting multiple delimited items from a single string.
Lookahead and lookbehind in practice
Lookarounds let you assert context around a match without including that context in the matched text — they are “zero-width” assertions:
(?<=\$)\d+(\.\d{2})? — match the number after a dollar sign, not the sign itself
\d+(?= items) — match a number only when followed by " items"
(?<!un)happy — match "happy" but not "unhappy"
Engine differences to watch:
- JavaScript does not support variable-length lookbehind in older environments; ES2018 added it but coverage varies
- Python’s
remodule does not support variable-length lookbehind; use theregexmodule instead - PCRE supports variable-length lookbehind fully
Character class shorthands by engine
| Shorthand | PCRE | JavaScript | Python |
|---|---|---|---|
\d | [0-9] | [0-9] | [0-9] (ASCII mode) |
\w | [a-zA-Z0-9_] | [a-zA-Z0-9_] | [a-zA-Z0-9_] (ASCII) |
\s | Whitespace chars | Whitespace chars | Whitespace chars |
| Named groups | (?<name>...) | (?<name>...) | (?P<name>...) |
Unicode behaviour (whether \d matches non-ASCII digits) varies significantly; consult your engine’s documentation when working with non-ASCII input.