Regex Tester
Type a regular expression and some text to see every match highlighted and each capture group extracted as you type, with the flags you choose. It runs on your browser's own JavaScript regex engine. Start from a recipe for email, URL, IPv4, semver or UUID.
More from RegexCalc
Guides
Frequently Asked Questions
Is my pattern or test data sent to a server?
No. Matching runs in your browser using the JavaScript engine itself, so neither your pattern nor your test string is transmitted.
Why does my pattern work here but not in grep?
This tester uses the JavaScript regex dialect: no delimiters, ECMAScript syntax, and whichever of the g, i, m, s flags you tick. That means lookahead, named capture groups, and — on modern engines — lookbehind all work, but \A, \z, \h, possessive quantifiers, and atomic groups do not. grep -E uses POSIX ERE and grep -P uses PCRE, so the same pattern can behave differently in each.
What is catastrophic backtracking?
A pattern with nested quantifiers, such as (a+)+, can require exponential time against a non-matching input and freeze the page. The tester evaluates in your browser, so it can hang that tab rather than a server. Rewrite the pattern with atomic-style rewrites or character classes that cannot overlap.
🧭 Pro Tips & Gotchas
JavaScript is not your regex engine
- The tester compiles a plain
new RegExp(pattern, flags)literal — no leading/trailing/.../slashes. Paste a/^a./gistyle regex and those slashes become part of the pattern and match nothing. - No named groups and no backreferences? Wrong direction: named groups (
(?<year>\d{4})) work in any current browser, so prefer them over counting group numbers in your head. .never matches\nunless you add thesflag. A pattern that passes your single-line tests can still silently swallow a multi-line input in production.^and$mean start/end of input with nomflag. Addmand they become line anchors — the single most common cause of "it matched locally but not on the site".
Gotchas that bite in production
\dmeans[0-9], not "any digit". Unicode digits like٣(Arabic-Indic) fail\dand pass\p{Nd}— and\p{...}needs thev(oru) flag.- Unescaped
.matches any character, soa.comalso acceptsaxcom. Escape literal dots in domains and IP patterns. - Greedy
.+will eat as much as the input allows;.?is lazy but backtracking-heavy. On user-supplied strings that is the shape that enables catastrophic backtracking — prefer explicit character classes over.. - Alternation is ordered and first-match-wins:
cat|categorynever reachescategory. Put longer alternatives first, or wrap with a boundary. - In a replacement string,
$&is the whole match and$'is the remainder of the string, not a literal quote. Use$$for a literal dollar sign. String.replace(str, re)replaces once;replaceAllneeds a global regex or a string pattern. Silently replacing only the first hit is a classic data-corruption bug.test()on a global (g) regex advanceslastIndexbetween calls, so the same regex object alternates true/false over equal inputs. ResetlastIndexor drop thegflag.