Regex Tester

Test a regular expression against sample text and watch matches, capture groups, and the replacement result update as you type.

/ / g
Flags
Matches
 
Capture groups
Start from a pattern

Runs entirely in your browser. Nothing you paste here is uploaded, logged, or sent to analytics.

This tests the JavaScript engine

Regex is not one language. A pattern that works here may not compile in Python, Go, Java, or PCRE, and — worse — may compile but match different things. If you are developing a pattern to use elsewhere, these are the differences that actually cause trouble:

FeatureJavaScriptElsewhere
Lookbehind (?<=…) Supported, and variable-length. PCRE and Java require fixed-length lookbehind; Go/RE2 has none at all.
Backreferences \1 Supported. Unsupported in RE2 (Go regexp, and most log/search engines built on it).
Possessive quantifiers a*+, atomic groups (?>…) Not supported. Available in PCRE and Java — a common reason a copied pattern fails to compile here.
Named groups (?…), referenced as \k. Python uses (?P…); converting requires editing both the definition and the reference.
$ at end of string Also matches before a trailing newline only with the m flag. Python $ matches before a trailing newline by default — a frequent off-by-one when porting.
Unicode property escapes \p{L} Requires the u (or v) flag. Available by default in most other engines.

Flags

FlagNameEffect
g global Find every match, not just the first.
i ignore case Case-insensitive matching.
m multiline ^ and $ match at line breaks, not just string start/end.
s dotAll . matches newlines too.
u unicode Treat the pattern as a sequence of code points; enables \p{…} property escapes.
y sticky Match only at lastIndex — no scanning forward.
d indices Record start/end offsets for each capture group.

The g flag has a sharp edge outside this tool: a global RegExp object carries a mutable lastIndex, so calling test() on the same regex twice can return true then false for identical input. Either create the regex fresh each time or avoid g with test().

Named groups beat numbered ones

(?<year>\d{4}) instead of (\d{4}) costs nothing and survives someone inserting a group in the middle six months later. Reference them as \k<year> inside the pattern and $<year> in a replacement.

Python writes the same thing as (?P<year>…) — one of the few syntax differences you have to fix by hand when porting a pattern.

Catastrophic backtracking

Patterns with nested quantifiers over overlapping character classes — the classic being (a+)+$ — can take exponential time on input that almost matches. This is the mechanism behind ReDoS, and it has taken down production services.

It cannot be prevented from inside a page that runs the match in the same thread, so this tool caps input length and match count instead, and tells you when a cap was hit. If a pattern here feels slow on short input, that is a real signal about how it will behave on a server. Rewrite it — usually by making the inner quantifier more specific — rather than shipping it.