What this does
Three fields — pattern, flags, and a test string — and everything below them
redraws on every keystroke. The test string is echoed back with every match
highlighted, and under it each match gets a card showing where it started and
what its capture groups caught. An invalid pattern shows the engine's compile
error instead of results. Your browser's built-in RegExp does the
work, so nothing you paste is transmitted.
How do I test a regular expression here?
- Type the pattern between the two slashes. Write it exactly as you would inside
/…/in code —\d, not\\d. No delimiters, no escaping of the escapes. - Set the flags in the narrow box on the right (it starts at
g). - Replace the test string with your own sample text.
- Read the count next to "Matches" and scan the highlighted block for anything you did not expect.
Matching is always global whether or not you type g — the flag is
added internally so the counter and the highlight can cover the whole string
rather than stopping at the first hit.
What does each match card tell me?
The header is #n @index followed by the matched text, where the
index is the zero-based character offset into the test string. Below it comes
one row per capturing group, numbered $1, $2 in the
order the opening parentheses appear; a group that took part in no alternative
shows as undefined rather than an empty string, which is the fastest
way to spot an optional group that never fired. Named groups are listed again
by name.
pattern (?<user>\w+)@(?<host>\w+)
text jane@example
#1 @0: jane@example
$1: jane
$2: example
?<user>: jane
?<host>: example What do the flags g i m s u y mean?
g— global; every match rather than the first. Always applied here.i— case-insensitive.m— multiline:^and$anchor to each line instead of to the whole string.s— dotAll:.also matches a newline.u— Unicode mode; required for\p{…}property escapes and for emoji to count as one unit.y— sticky; matching resumes only at the current position, so matches must be contiguous.
Anything the engine rejects — a repeated letter, an unknown one — surfaces as an error under the highlight, and the previous results are cleared.
Why does my pattern match more than I expect?
Greedy quantifiers, nearly every time. <.*> against
<a><b> produces one match spanning the whole string,
because * takes everything it can and only gives characters back
until the pattern succeeds. Make it lazy with <.*?>, or
better, say what you mean with a negated set: <[^>]*>,
which cannot overshoot at all and is faster on long inputs. A zero-width
pattern such as \b is the opposite surprise: it produces matches
with no text in them, listed as empty results at successive offsets.
Which regex flavour is this?
JavaScript's, as implemented by the browser you are reading this in, which is
close to but not identical to PCRE or Python's re. Named groups
are (?<name>…) and are backreferenced as
\k<name>, not (?P<name>…). Lookbehind,
positive (?<=…) and negative (?<!…), works in
current browsers. There are no possessive quantifiers, no atomic groups, no
recursion, no free-spacing flag and no inline modifiers like (?i).
Once a pattern behaves, take it to the
find and replace tool to apply it to a document, or
to sort lines and case conversion
for the tidying that usually follows.