Regex Tester
Test regular expressions with live match highlighting and groups.
Contact: ada@example.com and grace@navy.mil Backup addresses: hopper@example.org, invalid@@example Updated 2026-01-15 by team@example.co.uk
| # | Index | Match | Groups |
|---|---|---|---|
| 1 | 9 | ada@example.com | user: ada, domain: example.com |
| 2 | 29 | grace@navy.mil | user: grace, domain: navy.mil |
| 3 | 62 | hopper@example.org | user: hopper, domain: example.org |
| 4 | 121 | team@example.co.uk | user: team, domain: example.co.uk |
Contact: ada [at] example.com and grace [at] navy.mil Backup addresses: hopper [at] example.org, invalid@@example Updated 2026-01-15 by team [at] example.co.uk
About this tool
Write a pattern and see every match highlighted in your sample text as you type. Capture groups — including named ones — are broken out per match, and a replacement preview shows the result of a substitution before you commit it to code.
How to use it
- Enter your pattern and pick the flags you need.
- Paste sample text to test against.
- Inspect the match table, or try a replacement string.
Catastrophic backtracking, and how to spot it
Some patterns take exponential time on input that does not match. The classic shape is a quantifier inside a quantifier:
(a+)+$
Against aaaaaaaaaaaaaaaaaaaaX the engine tries every possible way to divide those characters between the inner and outer repeats before concluding there is no match. Add one character and the work doubles.
This is a real denial-of-service vector — "ReDoS" — because a request containing a crafted string can pin a CPU core for minutes.
The warning signs are nested quantifiers like (x+)+, (x*)* or (x|xy)+, especially followed by something that can fail.
The fix is to remove the ambiguity, usually by making the inner part unable to match the same text two ways. (a+)+$ becomes simply a+$. Where you genuinely need alternation, make the branches mutually exclusive.
Matching here is capped so a bad pattern cannot lock up the tab, but the pattern still needs fixing before it reaches a server.
This is JavaScript's flavour, not PCRE
Regex dialects differ more than people expect. This tester uses your browser's engine, so patterns behave exactly as they will in JavaScript — which is not exactly how they behave in Python, PHP, Go or grep.
JavaScript supports: named groups (?<name>...), lookahead (?=...), lookbehind (?<=...), and Unicode property escapes \p{Letter} with the u flag.
JavaScript does not have: atomic groups (?>...), possessive quantifiers a++, recursion, or \A and \z anchors. Patterns copied from a PCRE cheatsheet may need adjusting.
Go's RE2 is different again — it has no backreferences or lookaround at all, by design, precisely to guarantee linear time and avoid the backtracking problem above.
The m flag changes ^ and $ to match at line boundaries rather than only at the start and end of the whole string. It is the flag most often forgotten when a pattern works on one line and fails on many.
Frequently asked questions
- Which regex flavour is this?
- JavaScript's, as implemented by your browser. Lookbehind, named capture groups and Unicode property escapes all work. Patterns from PCRE, Python or Go may need small adjustments.
- Why does my pattern hang the page?
- Nested quantifiers such as (a+)+ can backtrack catastrophically on non-matching input. Matching is capped to protect the tab, but the fix is to rewrite the pattern to avoid ambiguous repetition.
- Is my test data private?
- Yes. The pattern is compiled and run by your browser's own regex engine. Log samples and production strings pasted here never reach a server.