Regex Tester — Test Regular Expressions Live
Matches highlighted as you type, with capture groups and a replacement preview.
🔒 Runs in your browser — files never uploaded ⚡ No signup 💯 Free
Matches
| # | Match | Position | Groups |
|---|
Replacement preview
Simplified layout on small screens — the full version is on desktop.
Type a regular expression and see every match highlighted in your test text as you type — no run button. Each match is broken down in a table with its position and every capture group, numbered and named, and a replacement preview shows what replace() would produce with your $1-style template.
The flavour is JavaScript's — the same engine as browsers and Node — which is also what most editors' find-and-replace understands.
How to use Regex Tester
- Type your pattern — without the surrounding slashes.
- Set the flags.
gis on by default so you see every match; addifor case-insensitive,mfor per-line anchors. - Paste test text. Matches highlight instantly and the table lists each one's groups.
- Open the replacement preview to try a substitution with
$1,$2or$<name>.
The flags, in practice
- g — find all matches rather than stopping at the first. You almost always want it on in a tester.
- i — case-insensitive.
- m — makes
^and$match at every line break rather than only the string's ends. The flag people forget when a line-based pattern "doesn't work". - s — lets
.match newlines, for patterns that span lines. - u — proper Unicode handling, and required for
\p{…}property classes like\p{Letter}.
Groups: your pattern's output
Parentheses don't just group — they capture. (\w+)@(\w+\.\w+) against an email captures the user as $1 and the domain as $2, which is what makes regex useful for extracting rather than just finding. Named groups read better in anything non-trivial: (?<user>\w+)@(?<domain>\w+\.\w+), referenced as $<user> in replacements. Use (?:…) when you need grouping without capturing — it keeps the numbering clean.
The classics that bite everyone
- Greedy matching:
".*"against"a" and "b"matches the whole thing. Quantifiers grab as much as possible; add?(".*?") for the shortest match. - Unescaped dots:
a.bmatches "axb". A literal dot is\.— the bug behind countless too-loose validations. - Catastrophic backtracking: nested quantifiers like
(a+)+$can take exponential time on non-matching input. If the page stutters on a pattern, that pattern is the reason.
When you're done testing
Run the real substitution over a document with the find & replace tool, which speaks the same regex flavour.
Frequently asked questions
Which regex flavour is this?
JavaScript's (ECMAScript) — the flavour browsers, Node and most editors' find-and-replace use. It differs from PCRE mainly at the edges: no possessive quantifiers or recursion, and lookbehind support arrived recently. For typical patterns the flavours agree.
Why does my pattern only find the first match?
The g flag is off. Without it a regex stops at the first match — that's also true in your code, where replace() without g replaces only the first occurrence. The tester keeps g on by default for exactly this reason.
Why do ^ and $ not match my lines?
Without the m flag they anchor to the very start and end of the whole text. Turn on m and they match at every line break — the intended behaviour for any line-oriented pattern.
What does "zero-length" mean in the match count?
Patterns like a* or a lone \b can match empty strings between characters. They're counted but not highlighted — marking nothing is invisible. A pattern producing mostly zero-length matches usually wants + instead of *.
Why does the page freeze on my pattern?
Catastrophic backtracking: nested quantifiers like (a+)+$ force the engine to try exponentially many paths on non-matching input. It's a property of the pattern, not the tester — the same pattern will hang your production code on hostile input, which is worth knowing before it ships.