VitalTools
...

Regex Tester

Build and debug regular expressions with live highlighting, a match table, and a replace preview — all in your browser

Pattern

//g
Mode
Cheat sheet
TokenMeaning
.Any character except line break
\dA digit (0-9)
\wA word character (letter, digit, underscore)
\sA whitespace character
\bA word boundary
^ $Start / end of string (or line, with m)
[abc]Any one of a, b, or c
[^abc]Any character except a, b, or c
a*0 or more of a
a+1 or more of a
a?0 or 1 of a
a{2,4}Between 2 and 4 of a
(…)Capturing group
(?<name>…)Named capturing group
(?:…)Non-capturing group
(?=…)Positive lookahead
(?<=…)Positive lookbehind
a|bEither a or b

Live Highlighting

Matches are highlighted in your test string as you type, no button to press

Groups at a Glance

A match table lists every capture, including named groups, side by side

Runs in Your Browser

Patterns and text never leave the page — nothing is sent to a server

Frequently asked questions

What flavour of regex does this use?

JavaScript's native RegExp engine — the same one that runs in your browser and in Node.js. Syntax mostly matches PCRE (used by PHP, Python's re with tweaks, and most online testers), but a few things differ: no possessive quantifiers or atomic groups, and lookbehind support depends on flag combinations. If a pattern behaves differently elsewhere, it is usually one of these gaps.

What do the flags mean?

`g` (global) finds every match instead of stopping at the first. `i` ignores case. `m` makes ^ and $ match the start/end of each line, not just the whole string. `s` lets . match newlines too. `u` enables full Unicode handling (needed for \p{...} property escapes). `y` (sticky) anchors matching to the exact position after the previous match. `d` adds match position indices, which this tool does not display but does not break either.

Why does my pattern only match once?

The `g` flag is off. Without it, JavaScript's regex engine — and this tool — only look for the first match. Turn on the `g` checkbox to find every occurrence, both for highlighting and for a Replace All.

Why is my capture group showing as "—"?

The group did not participate in this particular match. This happens with alternation like `(a)|(b)`: matching "b" fills group 2 but leaves group 1 undefined, because the `(a)` branch never ran. It is not an error — undefined groups are normal whenever a pattern has optional or alternative parts.

More Developer tools