Skip to content
TextArray

Regex cheatsheet

Regular expressions are compact enough that the syntax is easier to look up than to memorise. This page is the whole of it on one screen — classes, quantifiers, anchors, groups, lookaround, escaping and the flags — with a working example for every row.

The flavour is JavaScript, which is what runs in your browser and what the regex tester on this site uses. Most of it is identical in Python, Java, Go and PCRE; where flavours diverge, they diverge on the edges — lookbehind support, named-group syntax, and whether \d means "ASCII digit" or "any Unicode digit".

Two things account for most of the surprises. Quantifiers are greedy: they take everything they can and hand back only when the rest of the pattern fails, which is why <.+> swallows two tags and <.+?> does not. And alternation binds loosest of all, so ^a|b$ means "starts with a, or ends with b" — not what most people intend when they write it.

Character classes

The shorthands are ASCII-only unless you add the u flag and use Unicode property escapes.

SyntaxMeaningExample
.Any character except a line breakAdd the s flag to make it match newlines too./a.c/"abc" → "abc"
\dA digit, 0–9/\d+/"order 42" → "42"
\DAnything that is not a digit/\D+/"42abc" → "abc"
\wLetter, digit or underscoreASCII only — "é" is not \w./\w+/"user_1!" → "user_1"
\WAnything \w does not match/\W+/"a++b" → "++"
\sAny whitespace, including tabs and newlines/\s+/"a \t b" → " \t "
\SAny non-whitespace character/\S+/" hi" → "hi"
[abc]Any one of the listed characters/[aeiou]/"rhythm and" → "a"
[^abc]Any character except the listed ones/[^aeiou ]+/"aeiou xyz" → "xyz"
[a-z]A range of characters/[a-f]+/"zzabcz" → "abc"
\p{L}Any Unicode letter (needs the u flag)/\p{L}+/"42 café" → "café"

Quantifiers

All of these are greedy by default: they take as much as they can and give back only if the rest of the pattern fails.

SyntaxMeaningExample
*Zero or more/ab*/"a" → "a"
+One or more/ab+/"abbb" → "abbb"
?Zero or one — makes it optional/colou?r/"color" → "color"
{3}Exactly three/\d{3}/"id 12345" → "123"
{2,}Two or more/a{2,}/"aaa" → "aaa"
{2,4}Between two and four/a{2,4}/"aaaaa" → "aaaa"
*?Lazy — takes as little as possibleThe greedy <.+> would swallow both tags./<.+?>/"<a><b>" → "<a>"

Anchors and boundaries

These match a position, not a character, so they consume nothing.

SyntaxMeaningExample
^Start of the string, or of a line with the m flag/^a/"abc" → "a"
$End of the string, or of a line with the m flag/c$/"abc" → "c"
\bA word boundaryThis is what stops "cat" matching inside "concatenate"./\bcat\b/"the cat sat" → "cat"
\BNot a word boundary/\Bcat/"concatenate" → "cat"

Groups and alternation

SyntaxMeaningExample
(abc)Capturing group — remembered for replacement/(\d+)-(\d+)/"10-20" → "10-20"
(?:abc)Grouping without capturingUse this when you only need the grouping; it keeps capture numbers meaningful./(?:ab)+/"abab" → "abab"
(?<name>…)Named capturing group/(?<year>\d{4})/"in 2026" → "2026"
a|bEither side — alternationAlternation has the lowest precedence: ^a|b$ is "^a" or "b$", not "^(a|b)$"./cat|dog/"one dog" → "dog"
\1Backreference to the first group/(\w)\1/"letter" → "tt"

Lookaround

Assertions about what surrounds a position. They match nothing themselves, which is what makes them safe to combine.

SyntaxMeaningExample
(?=…)Lookahead — followed by this/\d+(?= kg)/"80 kg" → "80"
(?!…)Negative lookahead — not followed by this/\d+(?! kg)/"80 lb" → "80"
(?<=…)Lookbehind — preceded by this/(?<=\$)\d+/"costs $40" → "40"
(?<!…)Negative lookbehind — not preceded by this/(?<!\$)\b\d+/"about 40" → "40"

Escaping

These twelve characters are the ones that need a backslash to be taken literally.

SyntaxMeaningExample
\.A literal dot/\d\.\d/"v2.5" → "2.5"
\\A literal backslash/\\/"C:\\dir" → "\\"
\nA line feed/a\nb/"a\nb" → "a\nb"
\tA tab/a\tb/"a\tb" → "a\tb"
\uFFFFA character by its code point/\u00e9/"café" → "é"

Flags

FlagNameMeaning
gGlobalFind every match, not just the first.
iIgnore caseMatch regardless of upper or lower case.
mMultilineMakes ^ and $ match at every line break instead of only at the ends of the string.
sDot allLets . match line breaks too.
uUnicodeTreats the pattern as code points and enables \p{…} property escapes.
yStickyMatches only at exactly lastIndex, never searching forward.

FAQ

What is the difference between greedy and lazy quantifiers?
Greedy quantifiers (*, +, {2,}) match as much as possible and give characters back only when the rest of the pattern cannot match. Adding ? makes them lazy: they match as little as possible and take more only when forced. On "<a><b>", the pattern <.+> returns the whole string and <.+?> returns just <a>.
Why does my word match inside other words?
Because nothing anchored it. Wrap the word in \b — /\bcat\b/ matches "cat" in "the cat sat" but not inside "concatenate". \b matches a position between a word character and a non-word one, so it consumes nothing.
What does the u flag change?
It makes the pattern operate on code points rather than UTF-16 units, so a single emoji counts as one character, and it enables \p{…} property escapes such as \p{L} for "any letter". Without it, \w and \d stay ASCII-only, which is why "café" does not fully match /\w+/.
When should I use a non-capturing group?
Whenever you need the grouping but not the captured text — (?:ab)+ instead of (ab)+. Captures cost a little performance, but the real reason is numbering: every capturing group you add shifts the numbers of the ones after it, quietly breaking replacements that use $1 and $2.
Is lookbehind safe to use?
In current browsers and Node, yes — (?<=…) and (?<!…) have been supported across every major engine since 2018. Safari was the last to add it. If you are targeting very old runtimes, check first; there is no polyfill for regex syntax.