About this regex tool

A regex tester and pattern cookbook with no server behind it, built after noticing that every other regex tester on the web either sends your pattern somewhere to run it, or has no real answer for what happens when a pattern goes catastrophically wrong.

Why it exists

A regular expression is, by definition, meant to run wherever the text it is checking already lives. Every browser has shipped a complete, fast RegExp engine for decades. There is no technical reason a page that tests a pattern against some text needs a server at all — and yet a page holding a live connection can, and some do, forward what you type elsewhere. A pattern and a test string can carry exactly the same kind of sensitive content a JSON payload can: a fragment of a real log line, an internal hostname, someone’s actual phone number pasted in to check a validator against it. None of that needs to leave the tab it was typed into, so here it does not.

The second, more specific reason is safety rather than privacy. A regex engine can be made to do exponential work on a short, ordinary-looking pattern — catastrophic backtracking, covered in detail below — and a tester that runs your pattern directly on its own main thread has no way to recover if that happens except closing the tab. That failure mode shaped this tool’s architecture from the start, not as an afterthought bolted on later.

What it does

  • Tests a pattern against text with live match highlighting, as you type.
  • Explains a pattern token by token in plain English, without ever compiling or running it.
  • Substitutes, supporting $1$99, $&, $<name> and $$, exactly as String.prototype.replace understands them.
  • Warns on the textbook catastrophic-backtracking shape before running anything.
  • Copy-paste patterns for nine common problems — email, URL, phone, IPv4, ISO date, slug, hex colour and more — each with a dedicated page going into its trade-offs in depth.

How the timeout actually works

The one property that matters most for a page like this is that a bad pattern can never freeze the tab. Getting that property right took three layers, and it is worth being exact about what each one does, because two of the obvious approaches do not really deliver it.

A heuristic scan of the pattern’s text runs first, looking for the textbook catastrophic shape — a repeated group whose own contents can also repeat, like (a+)+. This is advisory only: it catches the well-known shape and nothing more, so it is shown as a warning, never as a block. A capped iteration count in the match loop sounds like the real safety net but is not — catastrophic backtracking happens inside a single call to the engine, before it ever returns to a loop that could count anything. The actual fix is that matching runs inside a same-origin Web Worker, with a timer started the moment a pattern is sent to it. If the worker has not replied by the deadline, Worker#terminate() kills it outright, even mid-exec(), and a fresh worker starts for the next attempt. Terminating a worker never touches the main thread, which is exactly why the page keeps responding to clicks and typing the entire time.

How the explainer stays safe on any input

The plain-English explainer is a second, entirely separate pass over the pattern’s raw text. It never compiles or runs the pattern, so it carries none of the backtracking risk described above no matter how pathological a pattern looks — there is nothing here for a hostile pattern to exploit, because nothing here executes it. It is a hand-written scanner rather than a full parser, recognising anchors, character classes and their shorthands, every kind of group (capturing, non-capturing, named, lookahead, lookbehind), backreferences, and the four quantifier shapes in both their greedy and lazy forms. A small number of exotic constructs fall back to a generic description rather than a precise one — a deliberate trade for explaining the constructs people actually write clearly, rather than handling every legal but rare one with equal precision.

One engine, honestly labelled

Every pattern on this site runs through JavaScript’s own RegExp, as specified in ECMA-262. That is close to, but not identical with, PCRE (PHP, most grep-style tools) or Python’s re. Some hosted testers support several languages’ engines at once, which is part of why they need a server — several of those engines only exist server-side. This tool tests exactly one engine, the one every browser already ships, so nothing needs to leave the page to test it. Each long-tail page notes the specific constructs (named-group syntax, lookbehind support, possessive quantifiers) that do not carry over unchanged to other flavours.

Never an unhandled error, never raw HTML from your input

Compiling, matching, explaining and substituting are all wrapped so that bad syntax produces a message, never a crash — try an unmatched [ or a bare * and you get the engine’s own explanation instead of a blank page. Every value that reaches the screen from a pattern or test string — the highlighted matches, the match list, the explanation, the substitution output — is written with textContent, never assembled into an HTML string. Paste <img src=x onerror=alert(1)> as test text and it renders as those literal characters, because no code path here turns your text into markup.

What it deliberately does not do

  • Test other regex flavours. One engine only — the one already in your browser. A tool claiming to test PCRE, .NET or Python regex client-side would either be wrong in the details or secretly running it somewhere else.
  • Guarantee a pattern is free of catastrophic backtracking. The heuristic warning catches one well-known shape. The worker timeout is what actually protects the tab, on every pattern, whether or not the heuristic recognised it in advance.
  • Parse HTML, JSON, or anything recursively nested. Regular expressions have no general answer to balanced nesting; that always needs a real parser.
  • Prove an email, phone number, IP address or URL is real. Every pattern here checks syntax. Confirming that something is reachable, deliverable or currently allocated needs an actual network request, which is out of scope for a page that runs entirely client-side.
  • Save or share anything. No accounts, no permalinks, no history. What you type exists only in this tab, for as long as this tab is open.

Known limitations

The catastrophic-backtracking heuristic is advisory and incomplete by design; it will miss danger hidden behind alternation or backreferences that a simple text scan cannot see. The explainer is a hand-written scanner, not a complete formal grammar for every legal JavaScript regex construct, and falls back to a generic description for the constructs outside its reference tables. Very large test strings, above roughly 200,000 characters, may be slow to highlight in full even against a perfectly safe pattern, simply because building a complete match list and highlighted view over that much text is real work; the iteration cap keeps this bounded rather than unbounded, at the cost of a truncation notice on genuinely enormous inputs. Lookbehind ((?<=…), (?<!…)) is unsupported in Safari before version 16.4 (March 2023); a pattern using it will throw there even though the syntax is entirely valid elsewhere.

Privacy and cost

Everything on this page runs client-side, including the worker that does the actual matching — it is a background thread of this same page, not a network destination. A pattern and test string are never transmitted, logged, or stored: there is no upload endpoint anywhere in this tool and no code path capable of using one. There is no account and nothing to install. Once the page and its worker script have loaded, nothing further is fetched, so it keeps working with the network disconnected.

The site is free to use. It may carry advertising to cover hosting; see the privacy policy for what that would mean. An advertising script is third-party code that makes its own requests, but it cannot see the contents of a pattern field or a test-text box it did not create, so “what you type never leaves your device” is a claim that survives it.

Why six long-tail pages instead of one big reference

The main cookbook page holds nine patterns side by side, each with a short description — useful for browsing, but too short a format to be honest about any one pattern’s trade-offs in depth. Email validation, in particular, deserves more than a sentence: the gap between “syntactically plausible” and “actually deliverable” is the single most common misunderstanding about this whole topic, and it needs room to explain properly, with a worked example, rather than a footnote. The six dedicated pages — email, URL, phone, IPv4, ISO date and slug — exist for that reason: each takes one pattern from the library and gives it the space to show what it matches, what it deliberately does not, and why, with the same live tester embedded so nothing here is only theoretical.

Corrections

If a pattern matches, fails to match, or is explained differently here than in your own JavaScript environment, that is worth hearing about — regex engines have edge cases even within one specification. Please include the exact pattern, flags, and input. The contact page has the address.