Regex Tester

Works offlineNothing is uploadedFree, no sign-up

Test a regular expression against your text with live highlighting, numbered and named groups, and a replace preview using JavaScript's own engine — with a kill switch for patterns that backtrack catastrophically, so the page never freezes.

A reading list for the pattern language

PieceMeansNote
\d \w \sdigit, word character, whitespacecapitals negate: \D is a non-digit
+ * ?one or more, zero or more, optionalappend ? for the lazy version
{2,5}between two and five repeats{2,} is two or more
[abc] [^abc]any of, none ofranges like [a-z0-9]
(x) (?:x) (?<n>x)capture, group without capturing, named captureprefer (?:) when the value is not needed
^ $ \bstart, end, word boundarywith m, per line
(?=x) (?!x)followed by, not followed byzero-width — they consume nothing

The two habits that prevent most regex bugs

Anchor what you mean. An unanchored pattern matches anywhere inside the text: \d{4} happily finds four digits inside a sixteen-digit card number. Validation patterns almost always want ^…$ around them. Escape what you paste. Fourteen characters are operators; a dot in a domain name or a plus in a phone number silently changes the pattern's meaning unless written \. and \+.

Matching runs locally in a worker thread; neither the pattern nor the text leaves your browser.

Frequently asked questions

Which regex dialect is this?

JavaScript's, exactly — the tool runs your pattern through the browser's own engine, so what matches here is what matches in your code, Node scripts and browser DevTools. Most syntax is shared with PCRE, but lookbehind support, \p{…} classes (with the u flag) and named groups follow the ECMAScript standard specifically.

What do the flags do?

g finds every match instead of the first; i ignores case; m makes ^ and $ match at each line break rather than only the text's ends; s lets the dot cross newlines; u switches to code-point mode, where one emoji is one character and \p{Letter} classes work. The flag combination is part of the pattern's meaning — the same expression with and without m can match completely different things.

Why did the tool stop my pattern after two seconds?

Catastrophic backtracking: a pattern like (a+)+$ on a long string of a's followed by one b forces the engine to try exponentially many ways of splitting the a's before concluding failure. The tool runs matching in a separate thread and kills it after two seconds — in your production code the same pattern would simply hang, which is a real denial-of-service class (ReDoS). The fix is restructuring so alternatives cannot re-divide the same text: replace nested quantifiers like (a+)+ with a single a+, and prefer explicit character classes over overlapping wildcards.

What is an empty match, and why does it appear at every position?

A pattern that can match zero characters — a*, \b, (?=x) — succeeds without consuming anything, so with the g flag it succeeds once at every position where it applies. The tool marks these with a thin caret. They are legitimate (that is how lookaheads and anchors work) but usually a sign the quantifier should be + rather than *.

How do I use the captured groups in the replacement?

The replacement field speaks String.replace's syntax: $1 to $9 for numbered groups, $<name> for named ones, $& for the whole match, and $$ for a literal dollar sign. A group that did not participate substitutes as an empty string — visible in the groups column as a dash.

Is my text or pattern uploaded anywhere?

No — matching runs entirely in your browser, in a worker thread on your own machine. Log lines, config files and the other texts people test patterns against are exactly the kind of data that should not travel; here it never does.

Related tools