This cheat sheet covers the regular expression tokens that handle daily work — classes, anchors, quantifiers, groups, lookarounds and flags — in the JavaScript flavor your browser runs.
Character classes, anchors and escapes
| Token | Matches | Example |
|---|---|---|
. | Any character except a line break (everything with the s flag) | a.c matches "abc" and "a7c" |
\d \D | A digit [0-9] / a non-digit | \d\d matches "42" |
\w \W | A word character [A-Za-z0-9_] / a non-word character | \w+ matches "id_42" |
\s \S | Whitespace (space, tab, newline) / non-whitespace | a\sb matches "a b" |
[abc] | One character from the set | [aeiou] matches "e" |
[^abc] | One character not in the set | [^0-9]+ matches "abc" |
[a-z] | A character range | [a-f0-9]+ matches "b4f" |
^ | Start of string (start of line with m) | ^ab matches start of "abc" |
$ | End of string (end of line with m) | ing$ matches end of "walking" |
\b \B | Word boundary / non-boundary position | \bcat\b matches "cat" but not the "cat" in "catch" |
To match a metacharacter literally, escape it with a backslash: \. a dot, \* an asterisk, \+ a plus, \( \) parentheses, \[ \] brackets, \{ \} braces, and \\ a backslash itself. Inside a character class most of these lose their meaning, so [.] already matches a plain dot.
Quantifiers, groups and lookarounds
Quantifiers: greedy vs lazy
| Token | Matches | Example |
|---|---|---|
* | Zero or more | ab* matches "a", "ab" and "abbb" |
+ | One or more | ab+ matches "ab" and "abbb", never "a" |
? | Zero or one | colou?r matches "color" and "colour" |
{n} | Exactly n | \d{4} matches "2026" |
{n,} | n or more | \w{3,} matches words of 3+ letters |
{n,m} | Between n and m | \d{1,3} matches "7", "42" and "350" |
*? +? ?? | Lazy versions: match as few as possible | see below |
Quantifiers are greedy: they take as much as possible, then backtrack only if the rest of the pattern needs it. On "<b>bold</b>", <.+> matches the whole string, because .+ runs to the last ">". A trailing ? makes any quantifier lazy: <.+?> stops at the first closing bracket and matches only "<b>".
Groups and alternation
| Syntax | Meaning | Example |
|---|---|---|
(abc) | Capture group, numbered left to right | (\w+)@(\w+) on "user@mail" stores "user" in $1 and "mail" in $2 |
(?:abc) | Non-capturing group: group without storing | (?:ab)+ matches "abab" |
(?<name>abc) | Named capture group | (?<year>\d{4}) stores "2026" as year |
a|b | Alternation: either side | cat|dog matches "cat" and "dog" |
\1 | Backreference to group 1 | (\w)\1 matches "ee" in "tree" and "oo" in "book" |
In find-and-replace text, $1 and $2 insert captured groups and $& inserts the whole match. Replacing (\w+)@(\w+) with $2@$1 swaps the two halves.
Lookarounds
| Syntax | Meaning | Example |
|---|---|---|
x(?=y) | Positive lookahead: x only if y follows | \d+(?=px) matches "16" in "16px", not in "16em" |
x(?!y) | Negative lookahead: x only if y does not follow | \d+(?!px) matches the "16" in "16em" |
(?<=y)x | Positive lookbehind: x only if y precedes | (?<=\$)\d+ matches "42" in "$42" |
(?<!y)x | Negative lookbehind: x only if y does not precede | (?<!un)known matches "known" but not the "known" in "unknown" |
Lookarounds are zero-width: they test a condition without consuming characters, so the checked text is never part of the match — ideal for extracting values next to known markers, like digits after a currency symbol.
Flags: g, i, m, s, u
| Flag | Effect | Example |
|---|---|---|
g | Global: find every match instead of stopping at the first | a with g on "banana" finds three matches |
i | Ignore case: uppercase and lowercase match alike | cat with i matches "Cat" and "CAT" |
m | Multiline: ^ and $ match at line breaks, not only at string ends | ^b with m matches a "b" at the start of any line |
s | dotAll: the dot matches line breaks too | a.b with s matches "a", a newline, then "b" |
u | Unicode: astral characters count as one unit and \p{L}-style classes work | \p{L}+ with u matches letters in any alphabet |
The Regex Tester also offers y (sticky), forcing each match to start exactly at the current position.
Five everyday patterns ready to copy
| Job | Pattern | What it accepts |
|---|---|---|
| Email-ish | ^[\w.+-]+@[\w-]+(\.[\w-]+)+$ | Most real addresses, like jane.doe+news@mail.example.com. A sanity check, not full RFC validation. |
| URL-ish | ^https?:\/\/[\w.-]+(:\d+)?(\/\S*)?$ | http(s) URLs with optional port and path, like https://sub.example.co:8080/a?b=1 |
| ISO date | ^\d{4}-\d{2}-\d{2}$ | Shape only: 2026-09-05 passes, but so does 2026-13-40. Strict version: ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ |
| IPv4-ish | ^\d{1,3}(\.\d{1,3}){3}$ | Four dot-separated numbers like 192.168.0.1; allows 999 too. Strict octets: ^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$ |
| Slugify | [^a-z0-9]+ → - (flags g i), then ^-+|-+$ → empty | "hello, world!" becomes "hello-world": replace runs of non-alphanumerics with a hyphen, then trim edge hyphens. |
Try it: paste a pattern above into the Regex Tester, add a sample line, and watch matches highlight live. Toggle the flag checkboxes to see what g, i, m, s and u change, or use the replacement field for the slugify two-step — everything runs in your browser, nothing is uploaded.