utilyfe

Regex Tester

Write a pattern, watch it match your text as you type, and check the groups it captures.

Runs entirely in your browser. Nothing you enter is uploaded or stored.

//gm

2 matches

Matches

  1. #1ada@example.comat 45–60
    Group 1
    ada
    Group 2
    example.com
  2. #2bob@example.orgat 158–173
    Group 1
    bob
    Group 2
    example.org

How to use the Regex Tester

  1. 1Type your pattern in the top box. The slashes and flags around it are shown for you.
  2. 2Switch flags on and off with the round buttons; hover one to see what it does.
  3. 3Paste your own text underneath. Matches are highlighted as you type, and listed with their capture groups.
  4. 4Press "Show replace" to try a replacement, using $1 for a numbered group or $<name> for a named one.

What the flags do

Flag Name Effect
g global Find every match rather than stopping at the first
i ignore case Cat matches cat
m multiline ^ and $ match at the start and end of each line
s dotall . also matches a newline
u unicode \u{1F600} works, and astral characters count as one
y sticky Match only at the exact position where the last one ended

m and s are the pair people mix up: m changes what the anchors mean, s changes what the dot means.

Greedy, lazy, and why .* eats too much

Quantifiers are greedy by default: they take as much as they can and give back only when the rest of the pattern fails.

Against <b>one</b> <b>two</b>:

  • <b>.*</b> matches the whole line, because .* runs to the end and backtracks only to the final </b>.
  • <b>.*?</b> matches just <b>one</b>. The ? makes the quantifier lazy: take as little as possible.
  • <b>[^<]*</b> is better still: it can’t cross a < at all, so there’s no backtracking to do.

The last form is the one to reach for. Being specific about what a wildcard may not contain is usually both clearer and faster than making it lazy.

Groups

  • (...) captures, and is numbered from left to right by its opening bracket.
  • (?<name>...) captures with a name, which is easier to read and survives a pattern being edited.
  • (?:...) groups without capturing: use it when you only need the brackets for alternation or a quantifier.

In a replacement, refer to them as $1 or $<name>. $& is the whole match, and $$ is a literal dollar sign.

Catastrophic backtracking

Some patterns take exponential time on input that almost matches. The classic shape is a quantifier inside a quantifier:

(a+)+$ against aaaaaaaaaaaaaaaaaaaaaaaaaaX

Each extra a doubles the work, so a few dozen characters can lock a tab, a server thread, or both. This tester runs patterns in a background worker and stops any that take more than half a second, so you get a warning rather than a frozen page. It’s the basis of a class of denial-of-service bug.

Signs to watch for: nested quantifiers, alternations that can match the same text in more than one way, and .* repeated in the same pattern. Anchoring the pattern and forbidding the delimiter inside a character class usually removes the problem.

Where JavaScript differs from other flavours

Feature JavaScript Elsewhere
Named groups (?<name>…) Python also allows (?P<name>…)
Lookbehind Supported Not in older PCRE builds, or in Go’s RE2
Inline flags Not supported (?i) works in PCRE, Python and Go
Atomic groups, possessive quantifiers Not available PCRE has both
\d, \w ASCII only unless you ask for unicode Often unicode-aware by default

If a pattern must run in another language, test it there too: this page is honest about being JavaScript’s engine rather than pretending to be universal.

Questions

Which flavour of regular expression is this?
JavaScript's own, running in your browser, so what works here works in JavaScript, TypeScript and Node exactly as shown. PCRE (PHP), Python and Go differ in places, most visibly around lookbehind, named-group syntax and inline flags like (?i).
Is my text sent to a server?
No. The pattern and the text stay in this tab, which matters when you're testing against a log extract or real customer data. Nothing is uploaded, logged or saved.
Why did my pattern seem to hang the page?
Nested quantifiers such as (a+)+ can make the engine try an exploding number of paths on text that nearly matches, known as catastrophic backtracking. It's a property of the engine, not this page. The tester runs your pattern in the background and stops it after half a second, so the page stays usable and tells you the pattern was too slow. Simplify the nesting, or anchor the pattern so it fails earlier.
How do I match across several lines?
Two different flags, often confused. The s flag lets . match a newline, so a pattern can run across lines. The m flag changes ^ and $ so they match at the start and end of every line rather than the whole text.
Why does my pattern match nothing after the first hit?
Without the g flag a regular expression stops at the first match. Switch g on to find every occurrence. That's also what makes replace change more than the first hit.