DEVELOPER TOOLS

JavaScript Regex Tester

Test a regular expression against sample text with live match highlighting, capture groups, and a replace preview. Entirely in your browser, nothing uploaded.

/ /

Engine: JavaScript RegExp (ECMAScript). Enter only the pattern — don't include surrounding /.../ delimiters; put flags like g, i, or u in the Flags field instead.

How to test a JavaScript regex

  1. Enter the regex pattern without surrounding /.../ delimiters.
  2. Add JavaScript flags such as g, i, m, s, u, v, y, or d.
  3. Paste your test text to see matches, capture groups, and indexes.
  4. Switch to Replace to preview JavaScript replacement strings.

For example, pattern \b\d{4}-\d{2}-\d{2}\b with flag g against the text "Order created on 2026-08-24" finds a single match, 2026-08-24, at index 17.

Regex flags

Flags change how a pattern matches, not what the pattern itself means character-by-character:

  • g (global) — find all matches instead of stopping at the first one.
  • i (ignore case) — match letters regardless of case.
  • m (multiline) — ^ and $ match the start/end of each line, not just the whole string.
  • s (dotAll) — . also matches newline characters.
  • u (unicode) — treats the pattern as a sequence of Unicode code points (correctly handling characters outside the Basic Multilingual Plane) and enables Unicode-aware features like \p{...} property escapes.
  • v (unicodeSets) — a newer superset of u mode with additional set-operation syntax inside character classes; cannot be combined with u.
  • y (sticky) — matches only starting at the exact current position, rather than searching forward for the next possible match.
  • d (hasIndices) — also records the start/end index of each capture group, not just the overall match.

Avoiding catastrophic backtracking

Some regex patterns can take an extremely long time to evaluate against certain input — long enough to freeze a browser tab indefinitely. This happens with patterns containing nested quantifiers (like (a+)+) or quantified alternation with overlapping branches (like (a|a)*) matched against input that almost, but doesn't quite, satisfy the pattern: the regex engine ends up trying an exponential number of ways to split the input among the repeated groups before giving up. For example, /^(a+)+$/ against "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!" (30 as followed by a character that can never match) can take longer than any reasonable timeout to fail — confirmed directly during this tool's own development, where that exact input hung a plain synchronous JavaScript process past a 3-second cutoff.

This tool evaluates every pattern inside an isolated Web Worker with an enforced timeout, specifically so a pathological pattern can't freeze the page — if evaluation takes too long, it's stopped and you'll see a clear message rather than an unresponsive tab. Separately, a fast heuristic checks the pattern's own shape for the nested-quantifier and overlapping-alternation cases described above and shows a warning before evaluation even starts. That heuristic is exactly that — a heuristic: it can flag patterns that are actually fine, and it can't catch every possible catastrophic shape (real-world catastrophic backtracking can be considerably more subtle than these two textbook cases). The timeout is the actual safety net regardless of what the heuristic concludes.

Frequently asked questions

Why does my non-global pattern only show one match?

That's standard JavaScript regex behavior, not a bug in this tool: without the g (global) flag, a pattern is only used to find the first match. Add g to the Flags field to find every match in the test string.

What happens to capture groups that don't participate in a match?

A group inside an alternation or an optional quantifier (like (a)|(b) or (a)?) can genuinely not participate in a particular match at all — JavaScript represents this as undefined, and this tool shows it explicitly as "(did not participate)" rather than an empty string, since those are two different, meaningful outcomes.

Is my pattern or test string ever sent anywhere?

No. Everything runs locally in your browser, including inside the Web Worker used for evaluation — nothing is uploaded or sent to any server.

Sources

Last reviewed: . All evaluation happens locally in your browser, inside an isolated Web Worker with an enforced timeout — nothing is uploaded.

Relevant, Not Routine

New tools and anything else worth knowing — sent occasionally, only when there's something real to say.