Regex Tester

Type a pattern and see matches instantly — highlighted, grouped and explained. Runs Rust's regex engines in your browser: your text and patterns never leave your device.

Files never leave your device
0

Test Regular Expressions Live, Privately

Type a pattern and a test string, and matches highlight as you type — no submit button, no round trip to a server. Everything runs client-side on a WebAssembly build of Rust's regex engines, so your text and pattern stay on your device the entire time.

The Copy link button packs your pattern, flags and test string into the URL's hash fragment (the part after #). Browsers never send the hash portion of a URL to a server on page load, so a shared link still keeps your data local to whoever opens it — nothing round-trips through us in either direction.

How to Use This Tool

  1. Write a pattern — Type or paste a regular expression into the Pattern field. Syntax errors are reported inline as you type.
  2. Set flags — Toggle i (case-insensitive), m (multi-line anchors), s (dot matches newline) and x (verbose, ignores whitespace and allows # comments) to change how the pattern is interpreted.
  3. Add a test string — Paste text directly, or use "Load from file" for larger inputs. Matches, groups and their spans are highlighted live.
  4. Explore the tabsMatch shows each match with its numbered and named groups; Replace rewrites the text using a replacement template; List extracts just the matched values, one per line; Explain breaks the pattern down piece by piece in plain language.
  5. Share or export — Copy a permalink that reproduces your exact pattern, flags and test string, or copy the replaced/listed output directly.

Linear-Time by Design

Most regex tools use a backtracking engine, which can take exponential time on adversarial input — the classic ReDoS (Regular Expression Denial of Service) problem, where a pattern like nested quantifiers can freeze a page or a server for seconds or minutes on a short, deliberately crafted string.

This tester avoids that by defaulting to Rust's linear-time regex engine wherever the pattern allows it. That engine guarantees matching time grows proportionally with input length — never exponentially — no matter what the pattern looks like. For the vast majority of patterns (character classes, quantifiers, alternation, groups, anchors) this is the engine that runs, and the badge next to the pattern field reads "Linear-time" to confirm it.

Two constructs fall outside what a linear-time engine can express: lookaround (lookahead/lookbehind) and backreferences. When your pattern uses either, the tool automatically switches to a bounded backtracking engine — still fully functional, but with a hard cap on backtracking steps. If a pathological pattern would otherwise run away, it stops with a clear error instead of freezing your browser tab. The badge then reads "Bounded backtracking" so you always know which engine compiled your pattern and why.

Flags Reference

The tester follows Rust's regex flag semantics:

FlagNameEffect
icase-insensitiveMatches letters regardless of case
mmulti-line^ and $ match at the start/end of each line, not just the whole string
sdot-matches-all. matches newline characters too (normally it doesn't)
xverbose/extendedWhitespace in the pattern is ignored and # starts a comment, so you can format complex patterns readably

Flags combine freely — for example im together for a case-insensitive, multi-line match.

Replace and List Modes

The Replace tab rewrites your test string using a replacement template in a code fence like:

$1-$2

Numbered groups are referenced as $1, $2, and so on in match order. Named groups defined with (?P<name>...) are referenced with the dollar-sign brace form:

${name}

The List tab strips away the surrounding text and shows just the matched substrings, one per line — handy for pulling every email address, URL or ID out of a block of text without writing a replacement template.

The Explain Tab

Regex syntax is dense, and even a pattern you wrote yourself can be hard to re-read weeks later. The Explain tab walks through your pattern token by token — character classes, quantifiers, groups, anchors and flags — as a plain-language tree, so you can confirm the pattern actually does what you intended before you rely on it in code.

Working With Other Text Formats

If your regex work is really about massaging structured data rather than free text, the JSON Formatter is a natural next stop — it validates, pretty-prints and lets you query JSON directly in the browser with the same zero-upload approach used here.

Frequently asked questions

Is my text or pattern uploaded to a server?
No. Matching runs entirely in your browser on a WebAssembly build of Rust's regex engines — your pattern and test string never leave your device. If you use the share link, the pattern is packed into the URL's hash portion, which browsers never send to a server, so even sharing a link keeps the data local to whoever opens it.
What makes this tool safe from ReDoS (catastrophic backtracking)?
Most patterns run on a linear-time engine, where matching time grows proportionally with input length, so runaway backtracking cannot happen no matter how the pattern is written. Only when a pattern needs lookaround or backreferences does the tool fall back to a backtracking engine, and that fallback is capped by a backtrack-step limit so a pathological pattern stops with an error instead of freezing your tab.
Why does my pattern show "Bounded backtracking" instead of "Linear-time"?
That label reflects which engine actually compiled your pattern. Lookahead, lookbehind and backreferences are outside what a linear-time engine can express, so those constructs are routed to a separate backtracking engine with a hard step cap. Everything else compiles to the linear-time engine, which is labeled accordingly.
Are there limits on input size or number of matches?
Yes. Test strings are capped at 10 MB, and the match panel displays up to 5,000 matches; beyond that, a truncation notice tells you more matches exist. Both limits exist to keep the browser tab responsive rather than to restrict functionality — nearly all real-world inputs fall well under them.
Does it support named capture groups?
Yes. Wrap a group with question-mark-P and the name in parentheses to define a named group, and its value will show up labeled by name in the Match tab alongside numbered groups. Named groups also work in Replace mode using dollar-sign brace references.
Which regex flavor does the tester use?
It uses Rust's regex crate semantics, which is close to PCRE for everyday patterns but does not support lookaround or backreferences on the linear-time path. Those two constructs are handled by the separate bounded backtracking engine described above, so both flavors of pattern work — you just get an accurate label for which engine is running.