How live match highlighting works
Paste a block of log output, type a pattern, and every match lights up before you finish the
thought. The tester runs your pattern through the browser's native RegExp engine on a short
debounce, so feedback arrives as you type instead of after a button press. Highlights render in
an overlay that sits pixel-aligned behind the text you are editing, which means you keep your
cursor, your selection, and your scroll position while you experiment.
How capture groups are tinted
Capture groups get their own treatment. Behind the scenes, the tool compiles every pattern with
the hasIndices flag, which makes the engine report the exact start and end offsets of each group
rather than forcing the tool to guess by re-searching substrings.1
Each group receives one of five rotating tints inside the wider match highlight, and the inspector
beside the editor lists the active match with every group's number, name, text, and character range.
A concrete pattern makes the group inspector easier to picture. Typing (\d{3})-(\d{4}) against
the test string Call 555-1234 now highlights 555-1234 as the full match, with
group 1 capturing 555 and group 2 capturing 1234. The inspector lists both
groups with their exact character offsets the moment the pattern compiles, so you can confirm the split
is landing where you expect before wiring the pattern into real code.
Why some patterns freeze other testers
Some patterns can freeze a browser tab solid. A regular expression like (a+)+$ tested against a
long run of the letter a forces the engine to try an exponential number of ways to split the
input, a failure mode called catastrophic backtracking; security literature names the attack that
exploits it ReDoS, short for regular expression denial of service.2
Most online testers run your pattern on the page's main thread, so one careless quantifier stops
the whole tab from responding.
How this tester contains runaway patterns
This tool treats that risk as a design requirement. Every evaluation runs inside a dedicated Web Worker, a separate thread that cannot block the page you are looking at.3 If the worker fails to answer within 500 milliseconds, the tool terminates the entire thread, spins up a fresh one for your next keystroke, and tells you which kind of pattern usually causes the blow-up.4 Your tab keeps scrolling the whole time.
This hard stop is what keeps the interface responsive. Once the worker is terminated it cannot resume, so the tester spins up a fresh worker for your next keystroke and hands the new evaluation to it. The main thread never waits on the doomed computation, which is why you can keep typing and scrolling while a runaway pattern is still being abandoned.
Find and replace with group references
Testing a match is only half the job, because most patterns exist to rewrite text. In Replace mode, the match highlighting stays visible on your test string while a second field accepts a replacement template, and the substituted result updates live underneath. You see what will be replaced and what it becomes at the same moment, which catches off-by-one group references before they reach your codebase.
The template follows the exact semantics of JavaScript's String.replace, so whatever works here
works unchanged in your code.5 Write $1 or $2 to
insert numbered capture groups, $<name> to insert a named group, $& for the whole
match, and $$ for a literal dollar sign. When the g flag is on, the engine rewrites every
occurrence; without it, only the first. Because replacement runs through the same worker and
timeout guard as matching, a pathological pattern cannot freeze the preview either.
Treat your pattern like code
A regex that works on one happy-path string is not finished. Unit Tests mode lets you pin the behavior down the way you would pin down a function: add a list of short test strings, mark each one as should match or should not match, and watch a live pass count while you refine the pattern. Negative cases matter as much as positive ones, since the most common regex bug is matching more than you intended.
Work through positive and negative cases
For an email pattern, for example, you might assert that [email protected] passes, that a bare word fails, and that a string with two @ signs fails. Every edit to the pattern re-runs all rows in a single batch, and each row shows an immediate PASS or FAIL badge next to its expectation. When you share the link, the whole suite travels with it, so a teammate opens not just your pattern but the evidence that it works.
Share links without giving up privacy
Nothing you type here leaves your machine. Matching, replacement, unit tests, and the explainer all run inside your browser tab against JavaScript's built-in regular expression engine, and you can cut the network connection after the page loads to confirm it for yourself.6 There is no account, no server-side history, and no request that carries your pattern or test data anywhere.
Sharing works without giving that up. When you click Share, the tool serializes your pattern, flags, mode, test string, replacement template, and unit test rows into a compact encoded string, writes it into the page address, and copies the full link to your clipboard. The state lives entirely inside the URL, so it reaches exactly the people you send it to and nobody else. Until you press that button, nothing is encoded anywhere at all.
Pattern-Is-Working Checklist
- Capture groups match what you expect Check the inspector lists the right text and character range for every numbered or named group, not just the overall match.
- No "pattern took too long" warning That message means catastrophic backtracking — nested or overlapping quantifiers such as (a+)+ are the usual cause.
- Flags match your real code A pattern tested with g or i toggled on behaves differently once those flags are missing in your actual code.
- Negative test cases fail correctly A regex that only matches the happy path is unfinished — add strings that should not match in Unit Tests mode.
Run your own pattern and test text above and check it against this list before shipping it.
- 1.
MDN Web Docs, "RegExp.prototype.hasIndices," developer.mozilla.org, accessed July 2026. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/hasIndices
- 2.
OWASP Foundation, "Regular expression Denial of Service - ReDoS," owasp.org, accessed July 2026. https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- 3.
WHATWG, "HTML Standard: Web workers," html.spec.whatwg.org, accessed July 2026. https://html.spec.whatwg.org/multipage/workers.html
- 4.
MDN Web Docs, "Worker: terminate() method," developer.mozilla.org, accessed July 2026. https://developer.mozilla.org/en-US/docs/Web/API/Worker/terminate
- 5.
Ecma International, "ECMAScript® 2026 Language Specification (String.prototype.replace)," ECMA-262, tc39.es, accessed July 2026. https://tc39.es/ecma262/#sec-string.prototype.replace
- 6.
"Regular expression," Wikipedia, accessed July 2026. https://en.wikipedia.org/wiki/Regular_expression