Regex Tester
- 2
- Matches
- 2
- Groups per match
- g
- Flags
Contact ada@example.com or grace@navy.mil for details.
| # | At | Match | Groups |
|---|---|---|---|
| 1 | 8 | ada@example.com | 1: ada · 2: example.com |
| 2 | 27 | grace@navy.mil | 1: grace · 2: navy.mil |
The tester runs a regular expression against sample text and shows what it matched, where, and what each capture group caught. Every flag is labelled with what it does rather than just its letter, since the difference between a pattern that works and one that does not is usually a flag.
How it works
The pattern is compiled with the JavaScript regular expression engine, the same one that runs in your code, so a pattern that works here works there. Patterns written for PCRE, Python or .NET may behave differently, since lookbehind support, named group syntax and some escapes vary between flavours.
- Matches are highlighted in the sample text, so overlapping expectations and unexpected greediness are visible immediately.
- Numbered and named capture groups are listed per match, with groups that matched nothing shown explicitly rather than omitted.
- The replace preview accepts $1 for a numbered group and $<name> for a named one, which is where most replacement mistakes show up.
- Matching stops at 1,000 results, and a zero-length match advances the position by one to avoid an infinite loop.
One thing this cannot protect you from is catastrophic backtracking. A pattern with nested quantifiers such as (a+)+b can take exponential time on input that nearly matches, and because JavaScript regular expressions run synchronously, a pattern like that will freeze the page rather than time out. Keep test input short while developing a pattern with nested repetition.
Examples
Two capture groups
Pattern
(\w+)@(\w+\.\w+)
Text
Contact ada@example.com or grace@navy.mil
Result
2 matches, 2 groups each, ada / example.com and grace / navy.mil
The local part and the domain are captured separately, which is what makes a replacement able to rearrange them.
Greedy against lazy
Pattern
<.+> against <.+?>
Result
One long match against several short ones
Greedy .+ runs to the last > in the text. Adding ? makes it stop at the first. Seeing both highlighted is the fastest way to understand the difference.
A replacement using groups
Replace with
$2: $1
Result
example.com, ada
Group references are $1 and $2 in JavaScript. Patterns copied from Python use \1 and \2, which will be inserted literally here.
Frequently asked questions
Which regular expression flavour is this?
JavaScript, using the browser's own engine. That is a feature if you are writing JavaScript and a trap otherwise: PCRE, Python and .NET differ on lookbehind, named group syntax, some escapes and possessive quantifiers. A pattern from a Python answer may not compile here, and vice versa.
Why did my pattern freeze the page?
Catastrophic backtracking. Nested quantifiers such as (a+)+b make the engine try exponentially many combinations against input that almost matches. JavaScript regular expressions run synchronously with no timeout, so nothing can interrupt it. Rewrite the pattern to avoid nesting a quantifier inside another.
How do I reference a capture group in the replacement?
$1, $2 and so on for numbered groups, $<name> for named ones, and $& for the whole match. A literal dollar sign is $$. Backslash references like \1 are the Python and PCRE convention and will appear literally in JavaScript output.
What does the global flag actually change?
Without it, matching stops at the first result and a replace only changes that one. Matching here always runs globally so you can see every match, but remember the distinction in your own code. A replace without the g flag is a very common bug.
Why does a group show as no match when the pattern matched?
Because the group is inside an optional part that was not used, as in (a)?b matching "b". The group exists in the result and holds undefined rather than an empty string. Code that assumes a group is always populated breaks on exactly this case, which is why it is shown rather than hidden.
Can I match across multiple lines?
Two different flags do two different things. Multiline makes ^ and $ match at each line break instead of only at the ends of the text. Dot-matches-newline lets . cross a line break, which it otherwise never does. Patterns that fail on multi-line input are almost always missing one of them.