Regex Tester
Type a pattern and instantly see what it matches – with color-coded highlighting right in the text, capture groups broken down next to it, and a replace preview. Choose between the JavaScript, Java, PCRE and Python flavors. ↓ Jump to the cheat sheet
Matches
Replace
Uses the same syntax as String.replace(): $1, $2 … for numbered groups, $<name> for named ones, $& for the whole match.
Runs in an isolated Web Worker with a time limit – nothing is uploaded, and a hanging pattern can't block the page.
Regex flavors: JavaScript, Java, PCRE, Python
Evaluation always runs on your browser's native RegExp engine — a purely static page with no server can't run an actual Java or Python interpreter. The flavor picker adapts what makes sense to show: for Java, PCRE and Python the JS-specific g flag disappears (those always search for every match anyway), and well-defined differences like Python's (?P<name>…) groups or the \A/\z anchors get translated to their JS equivalent automatically. For constructs with no JS equivalent — possessive quantifiers, atomic groups, POSIX classes — you get a warning instead of a silent wrong result.
Regex cheat sheet
The most important building blocks at a glance — including the flavor differences above:
Anchors
^ | Start of the string (or line with the m flag) |
$ | End of the string (or line with the m flag) |
\b | Word boundary |
\B | Not a word boundary |
Character classes
. | Any character except a line break (also matches it with the s flag) |
\d / \D | Digit / non-digit |
\w / \W | Word character (a-z, A-Z, 0-9, _) / non-word character |
\s / \S | Whitespace / non-whitespace |
[abc] | One of the characters a, b or c |
[^abc] | None of the characters a, b or c |
[a-z] | A character in the range a to z |
Quantifiers
* | 0 or more |
+ | 1 or more |
? | 0 or 1 (optional) |
{n} | Exactly n times |
{n,} | At least n times |
{n,m} | Between n and m times |
*? +? ?? | Non-greedy: as few as possible instead of as many as possible |
Groups & backreferences
(...) | Capturing group (numbered) |
(?:...) | Non-capturing group |
(?<name>...) | Named capturing group |
\1 | Backreference to group 1 |
\k<name> | Backreference to the named group “name” |
a|b | Alternation: a or b |
Lookaround
(?=...) | Positive lookahead: followed by … |
(?!...) | Negative lookahead: not followed by … |
(?<=...) | Positive lookbehind: preceded by … |
(?<!...) | Negative lookbehind: not preceded by … |
Flavor differences
(?P<name>...) | Python syntax for named groups (JS: (?<name>...)) – this tool translates it automatically. |
\A \z | Java/PCRE/Python anchors for the absolute start/end of the string – JS has none, they get replaced automatically. |
a++ (?>...) | Possessive quantifiers and atomic groups (Java/PCRE) – not supported by the JS engine. |
[:alpha:] | POSIX character classes (PCRE) – JS has no equivalent for these. |
Protection against catastrophic backtracking (ReDoS)
Nested quantifiers like (a+)+b can make a regex engine try an exponential number of possibilities on certain inputs. In a browser that usually means the tab freezes, because RegExp.exec() runs synchronously and can't be interrupted from the outside. This tool therefore evaluates in its own Web Worker — if it doesn't respond within roughly two seconds, it gets hard terminated and replaced with a fresh one, with a note explaining the likely cause.
Frequently asked questions
Does my pattern really run in Java, PCRE or Python?
No, always in the browser's JS engine — see above. The flavor picker translates well-defined differences and warns about everything else, but it's not a real interpreter.
Is my input uploaded anywhere?
No. Pattern, test text and replacement stay entirely in the browser; even the Web Worker runs with no network access on the same device.
How does replace mode work?
Like String.prototype.replace(): $1, $2 … for numbered groups, $<name> for named ones, $& for the whole match. Java/PCRE/Python always replace every match; JavaScript only does with theg flag set — the tool shows you which case currently applies.
Why does the match list sometimes stop at 5000?
A deliberate cap against patterns that match virtually everywhere and would otherwise use unnecessary memory — most patterns never come close to it.