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

/ / g
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

  1. Type your pattern — without the surrounding slashes.
  2. Set the flags. g is on by default so you see every match; add i for case-insensitive, m for per-line anchors.
  3. Paste test text. Matches highlight instantly and the table lists each one's groups.
  4. Open the replacement preview to try a substitution with $1, $2 or $<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.b matches "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.