Regex Tester
Test and debug JavaScript regular expressions with live highlighting, capture groups, and step-by-step explanation.
Regex tester
Updates as you type(…) to capture it, or use (?<name>…) for a named group.How regular expressions work
A regular expression is a tiny pattern language for describing text. This tool uses the JavaScript engine (built into your browser), so every pattern you type here behaves exactly like new RegExp(…) in a .js file.
- Compile. The engine parses your pattern into an internal state machine. Syntax errors surface here — that is the “Invalid regex” box.
- Scan. The engine walks through the test string from left to right, trying the pattern at each position.
- Match or backtrack. When a token fails, it backtracks and tries another branch (alternatives
|, greedy vs. lazy quantifiers, optional groups). - Collect. With the
gflag it keeps going after each match; withoutgit stops at the first hit.
JavaScript vs. PCRE (PHP / Python)
If you’ve written regex in other languages, a few things differ:
- Flag letters are similar:
g i m s u. JS also hasy(sticky) andd(hasIndices). PCRE addsx(extended), which JavaScript does not support. - Lookbehinds
(?<=…)and(?<!…)work in modern JS engines but are variable-width-only in older ones. - Possessive quantifiers
a++,a*+and atomic groups(?>…)do not exist in JavaScript. - Recursion
(?R)and subroutine calls(?1)are PCRE-only. - Unicode property escapes
\p{Letter}require theuflag in JS.
Common pitfalls
- Greedy by default.
.*grabs as much as possible. To match the shortest thing, use lazy.*?. - Catastrophic backtracking. Nested quantifiers like
(a+)+$can freeze the browser on pathological inputs. Prefer possessive-style patterns that fail fast — e.g.\w+@\w+over(\w+)+@\w+. - Anchors need the right flag.
^and$match the start/end of the whole string by default. Add themflag to make them match per-line. - Dot stops at newlines. Use the
sflag when you need.to cross line breaks. - Escape inside character classes. Inside
[…]the only metacharacters are] \ ^ -. Everything else is literal — you do not need to escape.or*. - Global + exec() in real code:
RegExp.lastIndexis stateful. If you’re iterating matches in JS, either useString.matchAll()or resetlastIndex.
Worked examples
/(\w+)@(\w+\.\w+)/gMatches a word-character block, an @, then a word.dot.word. Two capture groups let you extract the local part and the domain. Real-world emails are more complex — the RFC 5322 grammar is far nastier — but this is enough for log scraping and form validation hints.
/\b(\d{4})-(\d{2})-(\d{2})\b/gThree fixed-width digit groups separated by dashes, wrapped in word boundaries so it does not match mid-string. For strict validation you’d also constrain months to 0[1-9]|1[0-2].
/\b(?:\d{1,3}\.){3}\d{1,3}\b/gA non-capturing group (?:…) repeated three times, plus a final octet. This matches the shape only — 999.999.999.999 passes. For strict validation, each octet becomes 25[0-5]|2[0-4]\d|[01]?\d\d?.
/(\d{4})-(\d{2})-(\d{2})/ → $3/$2/$1In the Replace tab, this turns every 2024-07-04 into 04/07/2024. $1, $2, $3 are back-references to the capture groups.
/<[^>]+>/g[^>]+ means “one or more non-> characters”. Faster and safer than a greedy .* because the character class cannot backtrack across tag boundaries. Still not a real HTML parser — use a DOM parser for anything serious.
When not to use regex
- HTML, XML, JSON. Use a parser. Regex can’t balance nested structures.
- Email RFC compliance. The full grammar is ~6 KB. Use a dedicated library or a simple "contains @ and a dot after it" check plus a verification email.
- Dates with calendar rules. Regex can match the shape, not leap years.
- Natural-language parsing. Almost always the wrong tool — reach for a tokeniser or an LLM.