Regex Tester
Test a JavaScript regular expression against your text. See highlighted matches, offsets, capture groups and replacement output as you type. Everything runs in your browser.
JavaScript RegExp · runs locally in your browser
Enter the pattern without surrounding slashes. Backslashes are entered once, for example \d+.
Matches
How to test a JavaScript regular expression
Enter the pattern without the surrounding / characters, choose flags and paste test text. The highlighted preview shows where each match starts and ends. The match list shows its zero-based index, length and every capture group. An unmatched optional group appears as undefined.
Enable Replace matches to preview JavaScript String.replace() output. For example, pattern (\w+)@(\w+) can use $1 and $2 in the replacement. The global flag controls whether all matches or only the first are replaced.
The tester uses your browser's native JavaScript engine. Large or complex expressions run in a separate browser worker and stop after one second, so a slow pattern does not freeze the page. For syntax and ready-to-use examples, see the JavaScript regex cheat sheet.
JavaScript regex flags
| Flag | Name | What it changes |
|---|---|---|
g | global | Find every match instead of stopping at the first. Required by matchAll() and replaceAll() with a regex. |
i | ignoreCase | Letters match regardless of case. |
m | multiline | ^ and $ match at the start and end of each line, not only of the whole string. |
s | dotAll | . also matches line breaks. |
u | unicode | Treat the pattern as code points, enable \p{...} property escapes and reject unknown escapes. |
v | unicodeSets | Everything u does plus set operations in classes, such as [\p{L}--[a-z]]. Cannot be combined with u. |
y | sticky | Match only at lastIndex; the search does not skip ahead. |
d | hasIndices | Add match.indices with the start and end offset of every group. |
Flags go after the closing slash in a literal (/\d+/g) or as the second argument to the constructor (new RegExp("\\d+", "g")). In a string passed to the constructor every backslash has to be doubled; in this tester and in a literal it is typed once.
JavaScript regex error messages
An invalid pattern throws a SyntaxError when the expression is created. Chrome, Edge and Node.js (V8) print the pattern followed by the reason; Firefox prints only the reason. These messages were captured in Chrome 151, Node.js 22 and Firefox 147.
Unterminated group
(abc
- Chrome / Node.js:
Invalid regular expression: /(abc/: Unterminated group - Firefox:
unterminated parenthetical
A ( has no matching ). Close the group, or escape it as \( if you meant a literal parenthesis.
Unmatched closing parenthesis
abc)
- Chrome / Node.js:
Invalid regular expression: /abc)/: Unmatched ')' - Firefox:
unmatched ) in regular expression
Escape the literal parenthesis as \) or add the missing (.
Nothing to repeat
*abc
- Chrome / Node.js:
Invalid regular expression: /*abc/: Nothing to repeat - Firefox:
nothing to repeat
A quantifier (*, +, ?, {n}) must follow a character or group. Escape it (\*, \+, \?) to match it literally. Possessive quantifiers from PCRE such as a++ produce the same error.
Unterminated character class
[abc
- Chrome / Node.js:
Invalid regular expression: /[abc/: Unterminated character class - Firefox:
unterminated character class
Close the class with ], or escape a literal bracket as \[.
Numbers out of order in a quantifier
a{3,1}- Chrome / Node.js:
Invalid regular expression: /a{3,1}/: numbers out of order in {} quantifier - Firefox:
numbers out of order in {} quantifier.
Write the minimum first: a{1,3}.
Invalid group
(?P<year>\d{4})- Chrome / Node.js:
Invalid regular expression: /(?P<year>\d{4})/: Invalid group - Firefox:
invalid regexp group
The syntax after (? is not one JavaScript knows. Python named groups (?P<name>...), inline flags (?i) and atomic groups (?>...) all end here. Use (?<year>\d{4}) for a named group and the i flag instead of (?i).
Invalid named capture referenced
(?<a>x)\k<b>
- Chrome / Node.js:
Invalid regular expression: /(?<a>x)\k<b>/: Invalid named capture referenced - Firefox:
invalid named capture reference in regular expression
\k<name> must name a group that exists in the pattern. Check the spelling, which is case-sensitive.
Duplicate capture group name
(?<a>x)(?<a>y)
- Chrome / Node.js:
Invalid regular expression: /(?<a>x)(?<a>y)/: Duplicate capture group name - Firefox:
duplicate capture group name in regular expression
Rename one of the groups. Recent Chrome and Firefox allow a repeated name only in different alternatives, as in (?<a>x)|(?<a>y); Node.js 22 still rejects that too.
Invalid escape (with the u or v flag)
\Aabc flags: u
- Chrome / Node.js:
Invalid regular expression: /\Aabc/u: Invalid escape - Firefox:
invalid identity escape in regular expression
With u or v, escaping a character that has no meaning is an error. Without those flags the same \A silently matches the letter A. Remove the backslash, or use ^ for the start of the string.
Invalid flags
abc flags: gg (or uv)
- Chrome / Node.js:
Invalid flags supplied to RegExp constructor 'gg' - Firefox:
invalid regular expression flag g
Each flag may appear once, and u and v cannot be used together. In a regex literal the same mistake is reported as a syntax error in the script.
Regex from Python or PCRE that fails in JavaScript
Patterns copied from Python, PHP (PCRE) or Perl are the most common source of the errors above. Some do not fail at all and silently match something else, which is worse. Checked against Python 3.15, Perl 5.34 and the JavaScript engines above:
| Feature | Python / PCRE | JavaScript |
|---|---|---|
| Named group | (?P<name>...) in Python (which rejects (?<name>...)); PCRE accepts both | Only (?<name>...). (?P<name>...) throws Invalid group. |
| Inline flags | (?i)abc | Invalid group. Use the i flag; recent Chrome and Firefox also accept a scoped (?i:abc), Node.js 22 does not. |
| Atomic group, possessive quantifier | (?>a+), a++ (Python 3.11+, PCRE) | Not supported. Emulate an atomic group with (?=(a+))\1. |
| String anchors \A, \z | Start and end of the string | No such anchors. Without u, \A silently matches the letter A. Use ^ and $ without the m flag. |
| Omitted minimum {,3} | 0 to 3 repetitions (Python, Perl 5.34+) | Matches the literal text {,3}; with u it is an error. Write {0,3}. |
| Unicode properties \p{L} | PCRE yes; Python's re rejects it (bad escape \p) | Needs the u or v flag. Without it, \p{L} matches the literal text p{L}. |
JavaScript has its own edge: lookbehind can be variable length, so (?<=\$\d*)\d works in JavaScript, while Python rejects it with look-behind requires fixed-width pattern.
Learn more
Regex Cheat Sheet for JavaScript Developers
Anchors, quantifiers, character classes, flags, named groups, lookaheads, and copy-paste patterns for email, URL, date, and more — with JavaScript method examples.
Why You Should Never Paste Sensitive Data Into Online Tools
API keys, JWT tokens, database URLs, passwords — pasting them into server-side tools is a real security risk. Learn what happens to your data and what client-side alternatives to use.
Related Tools
Frequently Asked Questions
Which regex engine does this tester use?▾
It uses the native JavaScript RegExp engine in your browser. Results match JavaScript RegExp behavior in that browser, including its supported syntax and flags. Other engines, such as Python, PCRE and Java, can behave differently.
What do the g and i flags do?▾
The g flag finds all non-overlapping matches instead of stopping after the first one. The i flag ignores letter case. You can combine them to find every match regardless of case.
Why does the tester show only one match?▾
Without the global (g) or sticky (y) flag, JavaScript RegExp.exec() returns the first match. Turn on g to find every non-overlapping match. Sticky (y) matches only at the current lastIndex, so it stops at the first gap.
How do I use capture groups in replacement text?▾
Use $1 for the first numbered group, $2 for the second, and $<name> for a named group. Use $& for the whole match. Replacement follows JavaScript String.replace() rules; the g flag controls whether every match is replaced.
Does the test text leave my browser?▾
No. The pattern, test text and replacement are processed locally in a browser worker. This tool does not send your input to a server or save it in browser storage.