Regex cheatsheet: the patterns you actually need

2026-08-29·Developer reference·3 min read·by Sourabh Singh

Regex cheatsheet: the patterns you actually need

Every regex construct worth memorising, the JavaScript-specific gotchas, and the ambiguity that makes a pattern hang the whole page.

Regex cheatsheet: the patterns you actually need

Quantifiers are greedy by default; add ? to make them lazy.  is the word boundary most people underuse. In JavaScript, a global regex reused across .test() calls is stateful via lastIndex. Nested quantifiers over the same characters cause catastrophic backtracking and hang the page.

Most regex use is a dozen constructs recombined. Here they are, plus the traps specific to JavaScript's engine.

Character classes

PatternMatches
.Any character except newline (unless s flag)
\d \DDigit / not a digit
\w \WWord character [A-Za-z0-9_] / not
\s \SWhitespace / not
[abc]Any one of a, b, c
[^abc]Any character except a, b, c
[a-z]Range

Note \w includes the underscore and excludes accented letters. For international text use \p{L} with the u flag.

Quantifiers

PatternMeaning
*Zero or more
+One or more
?Zero or one
{3}Exactly three
{2,}Two or more
{2,5}Two to five
*? +?Lazy - match as few as possible

Quantifiers are greedy by default. <.+> against <a><b> matches the whole string; <.+?> matches just <a>.

Anchors and boundaries

PatternMatches
^Start of string, or line with m flag
$End of string, or line with m flag
\bWord boundary
\BNot a word boundary

\b is the one most people underuse. \bcat\b matches "cat" but not "category" - usually what you meant.

Groups

/(\d{4})-(\d{2})/          // numbered groups
/(?<year>\d{4})-(?<month>\d{2})/  // named groups
/(?:https?):\/\//          // non-capturing

Named groups land in match.groups.year, which is far more readable than match[1] six months later. Use non-capturing groups whenever you group only for alternation - it makes the intent clear and is marginally faster.

Lookaround

/foo(?=bar)/    // foo followed by bar
/foo(?!bar)/    // foo not followed by bar
/(?<=\$)\d+/    // digits preceded by $
/(?<!\$)\d+/    // digits not preceded by $

Lookahead is universal. Lookbehind is supported in modern JavaScript engines but not in Safari before 16.4 and not in some other languages - check before shipping it to browsers.

Free toolRegex TesterTest a JavaScript regular expression against sample text, see every match with its position and capture groups, and get real errors for invalid patterns.

Flags

FlagEffect
gFind all matches, not just the first
iCase insensitive
m^ and $ match line boundaries
s. matches newlines
uUnicode mode - required for \p{...}
ySticky - match only at lastIndex

JavaScript-specific traps

lastIndex on global regexes is stateful. A regex literal with g reused across calls to .test() remembers where it stopped:

const re = /a/g;
re.test("a");  // true
re.test("a");  // false - lastIndex is 1

Create the regex inside the function, or reset lastIndex explicitly. This bug is subtle because it only appears on the second call.

String.match behaves differently with g. Without it you get capture groups; with it you get an array of full matches and no groups. Use matchAll when you want both.

Escaping in new RegExp. The argument is a string, so backslashes need doubling: new RegExp("\\d+"). Prefer literals when the pattern is static.

Catastrophic backtracking

The one regex bug that takes down a server.

/(a+)+$/.test("aaaaaaaaaaaaaaaaaaaaaaaaaaX")

Nested quantifiers over the same character create exponentially many ways to split the input. On a non-matching string the engine tries all of them, and the page hangs.

The tells: a quantifier applied to a group that itself contains a quantifier, or alternation where branches can match the same text - (a|a)*.

The fix is to remove the ambiguity. (a+)+ should be a+. (\w+\s?)+ should be [\w\s]+. If you cannot make it unambiguous, do not use a regex.

Validate emails with /^[^@\s]+@[^@\s]+\.[^@\s]+$/ and send a confirmation link. RFC 5322-compliant email regexes are hundreds of characters long, still reject valid addresses, and prove nothing about whether the mailbox exists.

Launch it where the numbers are checked

RankCert ranks products on domain control we verify ourselves. Listing is free and the link stays dofollow whether or not you display the badge.

Submit a product - free

Tools from this guide