Regex Cheat Sheet

A searchable regular expression cheat sheet for the JavaScript flavour: character classes, bracket sets, quantifiers, anchors, lookaround, groups and flags, each with an example.

Forty-one regex tokens with examples. Filter across tokens, descriptions and examples, then copy the syntax you need. Covers the JavaScript (ECMAScript) flavour used in browsers and Node.js.

Reading and writing regular expressions with confidence

A syntax table, not a tutorial

Regular expressions are dense by design. A pattern like ^(?:\d{1,3}\.){3}\d{1,3}$ packs an entire IPv4 validator into thirty characters, which is wonderful when you wrote it and miserable when you are reading someone else's. Most of the difficulty is not conceptual — it is that the vocabulary is large, terse and easy to half-remember.

This page is a lookup table for that vocabulary, organised the way patterns are actually built: what matches a single character, how to define your own character sets, how to say "repeat this", where to anchor the match, how to group and alternate, and which flags change the engine's behaviour. The filter searches tokens, descriptions and examples at once, so typing "lazy", "boundary" or "lookbehind" jumps straight to the row you half-remember.

Which flavour these tokens follow

Regular expressions are not one language. Grep, PCRE, Python, Java, Go's RE2 and JavaScript all share a common core but disagree at the edges. Everything listed here targets the JavaScript flavour defined by ECMAScript, because that is what runs in the browser, in Node.js and in most front-end tooling.

Three differences are worth calling out. First, lookbehind — (?<=...) and (?<!...) — is supported in modern JavaScript engines but absent from Go's RE2 and from older Safari versions, so patterns that rely on it are not portable everywhere. Second, JavaScript has no x verbose flag, so you cannot spread a pattern across multiple lines with comments the way Python allows; long patterns are usually assembled from string fragments instead. Third, \d and \w are ASCII-only by default in JavaScript, so \w does not match accented letters or CJK characters unless you switch to Unicode property escapes such as \p{L} with the u flag.

Writing patterns that stay maintainable

Two habits prevent most regex pain. The first is to anchor deliberately. An unanchored pattern searches for a match anywhere in the string, which is what you want when scanning and almost never what you want when validating. Adding ^ and $ turns "contains something that looks like a date" into "is a date", and that distinction is behind a surprising share of validation bugs.

The second is to prefer laziness and negated character classes over greedy wildcards. The classic mistake is <.+> on HTML-like text: because + is greedy, it swallows everything up to the last > on the line. Writing <.+?> or, better, <[^>]+> matches a single tag. The negated-class version is also considerably faster, because the engine never has to backtrack.

Finally, be aware of catastrophic backtracking. Nesting quantifiers, as in (a+)+b, can make the engine explore exponentially many ways to split the input before it concludes there is no match, which turns a validation call into a denial-of-service vector when the pattern touches user input. If a pattern contains a quantified group that itself contains a quantifier, rewrite it — usually a single character class with one quantifier does the same job in linear time. And when a pattern grows past a line or two, the honest answer is often that a real parser is the right tool and the regex is not.

Built in-house. The syntax table targets the JavaScript (ECMAScript) regular expression flavour and runs entirely in your browser.

Frequently asked questions

Which regex flavour do these tokens describe?
The JavaScript (ECMAScript) flavour, which is what runs in browsers, Node.js and most front-end tooling. The core syntax is shared with PCRE, Python and Java, so the vast majority of these tokens transfer directly, but check lookbehind and Unicode property escapes if you are targeting another engine.
Why does my pattern match more than I expected?
Almost always because a quantifier is greedy. Both * and + take as much as they can and only give characters back when the rest of the pattern fails. Add ? to make them lazy, as in .+?, or replace the wildcard with a negated class such as [^>]+, which is both more precise and faster.
What is the difference between a capturing and a non-capturing group?
(abc) stores what it matched so you can reference it later with \1 or read it from the results array. (?:abc) groups the tokens for quantifiers or alternation without storing anything. Use the non-capturing form when you only need the grouping; it keeps result indexes stable and slightly reduces overhead.
Why does \w not match accented or Chinese characters?
In JavaScript \w is defined as [A-Za-z0-9_] and is deliberately ASCII-only. To match letters from any script, use a Unicode property escape with the u flag: /\p{L}+/u matches letters in Latin, Cyrillic, Greek, Han, Kana and every other script.
Can a regular expression be a security risk?
Yes. Nested quantifiers such as (a+)+b can trigger catastrophic backtracking, where the engine explores exponentially many possibilities before failing. If such a pattern is applied to user input, a short crafted string can freeze the process. Rewrite nested quantifiers into a single character class wherever possible.
Should I use a regex to parse HTML or JSON?
No. Both are recursive formats and regular expressions cannot express arbitrary nesting. Use a real parser: DOMParser for HTML, JSON.parse for JSON. Regular expressions are the right tool for scanning flat text, validating simple field formats and doing targeted find-and-replace.