Cadmeo

Regex Tester

2
Matches
2
Groups per match
g
Flags
Matches in context

Contact [email protected] or [email protected] for details.

Captured groups
#AtMatchGroups
18[email protected]1: ada · 2: example.com
227[email protected]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+)

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.

Compared with

  • Regex Tester vs Find and Replacewhat you are matching varies, a date, an email address, anything with a shape rather than a fixed value : compared with find-and-replace