
Online Regex Tester: A Practical Guide to Debugging Regular Expressions
Test a JavaScript regex, inspect capture groups, and preview a $1 replace in the browser before the pattern lands in production code.
A pattern that looks right still deserves a failing input
A regular expression is a tiny program. It is easy to write, easy to paste from a comment thread, and expensive when it accepts the wrong string or hangs the tab. The online regex tester runs the browser's JavaScript RegExp engine on a pattern and a test string you paste locally — highlights on the left, match cards with groups on the right, and an optional replace preview. There is no flavor switch: it is not PCRE, not Python, not the engine inside a database. That is the same family as Node and as a JSON Schema pattern evaluated by Ajv. The page sits on the developer utilities hub, next to slugify and the case converter, for the jobs that should not be a hand-rolled expression at all.
Where the tester helps, and where a unit test should take over
A pattern you are about to paste into code, a fixture, or a JSON Schema pattern keyword.
Some jobs already have a tool that encodes the rules. A hand-written expression will drift.
Patterns that survive a glance and fail on real input
The tester compiles the field with new RegExp. Recursive constructs such as (?R) are invalid here and surface the engine's error. The slashes you see around the field are chrome, not part of the pattern. Pasting /(\w+)/gi unwraps the pattern and merges those flags with the ones already toggled — it does not replace them. If g was already on, it stays on. A second trap is the backslash: the field is the regex source, so \d means digits. Pasting \\d from a JSON or Java string looks for a literal backslash followed by d.
On "one" and "two", the pattern ".+" with g returns one match: the whole span from the first quote to the last. The engine takes as much as it can, then gives characters back until the final quote fits. Switching to ".+?" is not “only the words you meant as a phrase”. With g it returns two matches, "one" and "two". Lazy means the shortest success, not a semantic filter. "[^"]*" is the pattern that cannot cross a quote.
A shape such as (a+)+ against a long run of a's that never reaches the expected ending can explode into catastrophic backtracking. The tester has no server timeout. It runs on the tab's main thread, so the page can freeze. The tool does cap what it returns: global search stops and shows a truncation warning, either because it hit the soft cap of 500 matches, or because a zero-width pattern tripped the loop guard (the engine advances one character after an empty match so g cannot spin forever). That guard does not make a nested quantifier safe. Upload accepts .txt, .md, and .log up to 32 MiB into the test string, still locally — a full log plus a nested pattern is a good way to lock the tab.
The Email-ish chip is [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,} on [email protected] x not-an-email [email protected]. With g it highlights [email protected] and [email protected]. It is a demo, not RFC 5322, and the page says so. The same honesty applies to sticky mode: flag y matches only at the start of the test string here, because lastIndex is reset on every run. It will not “continue where the last match stopped” across clicks. And results do not update while you type. Changing the pattern, the flags, the mode, or the text clears the cards until you press Test again.
What each flag and mode actually changes here
Six flags, no others. Default is g alone.
Match lists hits. Replace also shows the substituted string, using JavaScript replacement patterns.
A named capture is the same group as its number. The card shows it once.
Run one case, then change a single variable
On the regex tester, nothing runs while you type. The previous cards clear as soon as the inputs change.
Write the source, not a literal
Type \d+, not /\d+/g. If you do paste a /pattern/flags literal, paste or blur unwraps it and merges flags. Empty pattern is an error. Invalid pattern shows the JavaScript message.
Toggle only the flag you mean to test
g is on by default. Turn it off to confirm you really wanted a single match. Add m before trusting ^ on a second line. Add u before \p{…} — without it, \p{L} matches the literal characters p{L}, not letters. Leave y off unless you are checking a match that must start at index 0.
Press Test and read the card, not just the highlight
The highlight shows where the hit sits. The card shows the index and each group. Click a card to emphasize that hit. In replace mode, read the substituted string under the cards before copying the pattern into code.
The chips are fixtures, not a library of production validators.
(\w+)=(\d+) on user=42 role=admin env=prod\d, \w, \s, ., [], ^, $, \b, +, *, ?, and () at the caret. Brackets and parentheses place the caret inside.txt, .md, or .log file up to 32 MiB into the test string, in the browser. Prefer a short excerpt when the pattern is not obviously linearThe same engine in Node
Node's RegExp is the same language. matchAll requires the g flag. Without g, use exec once.
Basic example
Replacement patterns are the ones the replace field accepts. This is the built-in chip, not a custom template language.
Basic example
No install, nothing uploaded, flags and groups visible, replace preview included. Trade-off: no flavor switch, sticky mode only at index 0, at most 500 returned matches, and a nested quantifier can freeze the tab because execution is local. Keep the page for a fixture and a code review. Commit the pattern beside tests when it guards production input. If the expression was only standing in for a slug or a case change, switch to slugify or the case converter instead of maintaining it.
Conclusion
Test the pattern against a string that should fail, in the engine that will run it. For JavaScript that engine is RegExp, which is what the regex tester uses — including a JSON Schema pattern you will later compile with Ajv in the JSON Schema validator. Do not treat the email-ish chip as a validator, do not expect flag y to resume mid-string, and do not feed a nested quantifier a 32 MiB log. When the job is a slug or a case change, leave the expression alone and use the dedicated tool on the developer utilities hub.
Related Articles

Random UUID v4, sortable UUID v7 and ULID, or compact customizable Nanoid: a comparison and online generators for primary keys, public IDs and tokens.

Compute an MD5 or SHA digest, or sign a message with HMAC, in the browser. Hex, Base64 or Base64URL — text checksums and webhook signatures, 100% local.

Skip SSH and nginx for a side-project Next.js app. Compare Railway, Render, Vercel and a VPS, then ship from Git after minifying assets in the browser.