Skip to main content
Back to BlogDeveloper Guides

How to Read a Regex Cheatsheet (68 Tokens Not 100, Four Flavors of Static Text, and a Tester That Throws on Its Own Cheatsheet)

Read the Regex Cheatsheet — and learn why the badge says 68 tokens while the FAQ says 100+, why the inline tester throws on five tokens the Cheatsheet tab teaches, why the four flavors are reading material not validation, and which common patterns lie about what they accept.

The Toolbox TeamAugust 14, 20267 min read

Copy \A from the Cheatsheet. Paste it into the Tester. It throws.

Open the Regex Cheatsheet Lookup, scroll to Anchors & Boundaries, copy \A — "Start of input (PCRE/Python — not JS)." Click the Tester tab, paste into Pattern, hit Test. You get Invalid regular expression: /\A/: Invalid escape. The Cheatsheet just taught you a token the Tester cannot run. Both tabs ship in the same component; they don't talk to each other.

The Cheatsheet is a static reference for four flavors, but the Tester is a JavaScript RegExp only. Five tokens (\A, \Z, \z, *+, (?>...)) plus the x flag are PCRE/Python — JS throws on every one. The flavor notes say so in prose the Tester never reads; it hands your string to new RegExp and surfaces the throw.

The badge says 68. The FAQ says 100+.

The toolbar renders {totalTokens} tokens from SECTIONS.reduce((sum, s) => sum + s.entries.length, 0). The FAQ and registry say "100+ regex tokens." The badge counts the array. Eight sections, 68 entries: Character Classes 13, Anchors 7, Quantifiers 11, Groups & Lookarounds 10, Alternation 2, Escapes 9, Flags 7, Unicode Properties 9.

68 is a fine count; "100+" is marketing the data doesn't back. Trust the badge. The Common Patterns panel reads {COMMON_PATTERNS.length} = 14, and 14 is what lands.

The Tester is JavaScript, and only JavaScript

Every match runs through new RegExp(testPattern, testFlags) in your browser. No flavor selector on the Tester tab — the four-flavor picker lives on the Flavors tab and changes nothing about evaluation. Cross from PCRE tokens into the JS tester and:

  • \A, \Z, \z throw. Use ^ and $ (with m for lines).
  • *+, ++, ?+ throw. JS has no possessive quantifiers.
  • (?>...) atomic groups throw. No equivalent in JS.
  • The x flag throws. Listed in Flags as "PCRE/Python," but the Tester hands it to new RegExp, which rejects it.

The global loop caps at 1000 matches (if (++guard > 1000) break). Empty matches are handled — if (m[0].length === 0) re.lastIndex++ prevents the infinite loop, and empties render as . \d* on "abc" won't hang the tab; it yields a row of empties.

The "Test" button strips the global flag

Each common pattern has a Test button that loads it into the Tester with testFlags = '' — empty, not g. Every library pattern is anchored with ^...$, so a single full-string match is the intent and works. Copy a pattern like \d+ (no anchors) out of the Cheatsheet and forget to add g, and you get one match and stop. The Sample button seeds flags with g. Two buttons, two flag defaults, no label.

Four flavors, four panels of prose

The Flavors tab cycles through JavaScript, Python (re/regex), PCRE, and POSIX — six bullet points of static text from a FLAVOR_NOTES object. The picker changes what you read; not what the Tester accepts or how the Cheatsheet filters. Treat it as a reading lamp, not a mode switch. The POSIX notes earn their keep: why grep -E doesn't understand \d (use [[:digit:]]), why sed wants \( \) for groups.

Common patterns that lie about what they accept

The 14 patterns are RFC-shaped, not RFC-complete. Three:

  • Strong Password allows special chars from [@$!%*?&] only. A password with #, ^, ~, or - fails despite being strong. Add the chars your users use.
  • IPv6 matches the full 8-group form only. 2001:db8::1 — the compressed form everyone writes — fails. The explanation says so; the badge still reads "IPv6 Address."
  • Email forbids + in the domain, quoted local parts, and IP literals. Fine for a form gate, wrong for an RFC 5321 parser.

Gotchas

  • The d flag is missing from Flags. The JS flavor notes list g, i, m, s, u, y, d (Indices, ES2022), but the Flags row stops at y and adds x. d is real; x isn't a JS flag.
  • Search only searches the Cheatsheet tab. The filter matches token, description, or example text — not pattern names or flavor notes. "email" returns nothing on Patterns.
  • escapeRegExp is dead code. Defined and never called; a hidden <span>{escapeRegExp('')}</span> suppresses the unused-warning. The Tester doesn't sanitize your pattern before compiling — correct, since you want raw regex.
  • Copy gives the literal token. \d copies as two characters, not \\d. Paste into a JS string and re-escape; into a regex literal, it works.

Summary

  • The badge says 68 tokens, the FAQ says "100+." Eight sections, 68 entries, 14 patterns, 4 flavor panels — trust the badges, which read from the arrays.
  • The Tester is JavaScript-only. Five PCRE tokens (\A, \Z, \z, *+, (?>...) and the x flag are taught in the Cheatsheet and throw in the Tester. The Flavors tab explains this in prose the Tester never reads.
  • The Test button loads patterns with empty flags (no g); Sample loads with g. Free patterns find one match unless you add g.
  • Common patterns are RFC-shaped, not RFC-complete: Strong Password rejects # and ^, IPv6 rejects :: compression, Email rejects + in domains.
  • The d flag is missing from Flags while the non-JS x flag is listed. Read the reference at Regex Cheatsheet; build at Regex Builder and the Regex Tester. Related: JSON Schema Generator, HTTP Headers Parser.