Regex Tester
Test regular expressions online with live match highlighting. Try patterns against sample text, inspect capture groups, and preview find-and-replace results instantly.
What is a regular expression?
A regular expression (regex) is a pattern that describes a set of strings — "four digits, a hyphen, two digits", "a word followed by @" — used to search, validate, extract or replace text. Most programming languages have a regex engine, and their syntax is similar but not identical. This tester uses JavaScript's built-in RegExp, as specified in the ECMAScript specification, so results are exactly what new RegExp(pattern, flags) gives in your browser. For syntax at a glance, see the regex cheat sheet.
How to use the regex tester
- Type the pattern into the pattern field at the top, without the surrounding slashes: enter
\d+, not/\d+/g. - Tick the flags you need: g, i, m, s or u. Only g is ticked by default.
- Paste text into Test string. Matches are highlighted in Highlighted matches as you type, and the Test string header shows the match count.
- Read the Matches list below: each match is shown with its number, its start index (counting from 0), the matched text and, if the pattern has capture groups, a
groups:array. If it has named groups, anamed:object with each group's name and value follows. - To preview a substitution, type into Replace with. Show replacement result is ticked automatically, and the list below becomes Replacement result, showing the whole test string after replacement. To preview deleting the matches, leave Replace with empty and tick Show replacement result yourself. Untick it to see the Matches list again.
There is no Run button: results update a moment after you stop typing, or straight away when you change a flag. Matching runs in a background Web Worker, so a slow pattern cannot freeze the page; if one run takes longer than 1.5 seconds it is stopped (see below). Copy Test String copies the text in the Test string pane, and Clear empties the pattern, test string and replacement and unticks Show replacement result.
JavaScript regex flags
| Flag | Name | Effect |
|---|---|---|
g | global | Find every match, not just the first. Also makes Replace with change every match. |
i | ignoreCase | Case-insensitive matching |
m | multiline | ^ and $ match at the start and end of each line, not just of the whole string |
s | dotAll | . also matches line breaks |
u | unicode | Treats the pattern as Unicode code points, enables \p{…} property escapes and rejects unknown escapes such as \a |
Common patterns, tested
Each pattern below was run through the same matching logic as this page. Simple patterns like these are good for searching and quick checks; for strict validation of email addresses or URLs, use a dedicated parser.
| Purpose | Pattern and flags | Result |
|---|---|---|
| Email address (basic check) | ^[^\s@]+@[^\s@]+\.[^\s@]+$ | Matches [email protected]; rejects jane@localhost and a [email protected] |
| URL in text | https?:\/\/[^\s]+ with g | In See https://example.com/docs and http://test.dev. finds 2 matches — the second includes the trailing full stop |
| Digits only | ^\d+$ | Matches 12345; rejects 12a45 |
| UUID | ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$ with i | Matches 3F2504E0-4F89-11D3-9A0C-0305E82C3301 |
| ISO date with groups | (\d{4})-(\d{2})-(\d{2}) with g | In Released 2024-03-15, patched 2024-04-02.: #1 index 9 "2024-03-15" groups: ["2024","03","15"] and #2 index 29 |
| Opening HTML tag | <(\w+)[^>]*> with g | In <p class="x">Hi</p><br/> finds <p class="x"> (group p) and <br/> (group br) |
| Number after a $ sign (lookbehind) | (?<=\$)\d+ with g | In Total $42 and $7 finds 42 and 7 |
| Words with accented letters | \p{L}+ with g and u | In naïve café finds naïve and café; without u there are no matches |
Replacement examples
The Replace with field uses JavaScript's String.prototype.replace syntax: $1, $2 … insert numbered groups, $<name> inserts a named group, $& inserts the whole match and $$ inserts a literal dollar sign.
| Pattern and flags | Replace with | Test string → result |
|---|---|---|
(\d{4})-(\d{2})-(\d{2}) with g | $3/$2/$1 | Released 2024-03-15, patched 2024-04-02. → Released 15/03/2024, patched 02/04/2024. |
(?<year>\d{4})-(?<month>\d{2}) with g | $<month>/$<year> | 2024-03 → 03/2024 |
(\w+) (\w+), no flags | $2, $1 | John Smith → Smith, John |
- with g | $&$& | a-b → a--b |
\s*\(draft\) with g | (empty, with Show replacement result ticked) | Report (draft) v2 (draft) → Report v2 |
Common errors and how to fix them
If the pattern cannot be compiled, an Invalid regular expression: message from your browser appears above the panes. The exact wording differs between browsers, but the cause is one of a few usual suspects.
| Pattern | Problem | Fix |
|---|---|---|
(abc | Unterminated group | Close every (; to match a literal bracket, escape it as \(. |
*abc | Nothing to repeat: a quantifier with nothing before it | Escape it (\*) to match a literal asterisk. |
[z-a] or a{2,1} | Range or quantifier bounds out of order | Write the smaller value first: [a-z], a{1,2}. |
\a with u | Unknown escape, rejected in Unicode mode | Remove the backslash, or untick u. |
/abc/g | No error, but the slashes and g are matched as literal text | Type only abc and use the flag checkboxes. |
Catastrophic backtracking
A nested quantifier such as ([^<]+)* or (a+)+ can make the engine try an exponential number of combinations when a match fails. ^(a+)+$ against aaaaaaaaaaaaaaaaaaaaaaaaaaaa! (28 letters and an exclamation mark) is enough to keep a regex engine busy for seconds. This tester runs the match in a Web Worker and stops it after 1.5 seconds: the message "Stopped after 1.5 seconds: the pattern is taking too long on this text, probably because of catastrophic backtracking…" appears above the panes, and the Test string header shows "timed out". Your own code has no such limit, so a pattern that times out here can hang a browser tab or a Node.js process. Remove the nesting ([^<]* instead of ([^<]+)*, ^a+$ instead of ^(a+)+$) or make the alternatives mutually exclusive.
Frequently asked questions
Why do I only see one match?
The g (global) flag is not ticked. Without it, a JavaScript regex stops at the first match, and this tester follows that behaviour exactly, both for highlighting and for Replace with. Tick g to find or replace every non-overlapping match.
How do I see capture groups?
Wrap part of the pattern in parentheses, for example (\d+). Each entry in the Matches list then ends with a groups: array in group order; a group that did not take part in the match is shown as null. Named groups such as (?<year>\d{4}) appear in that array by position and again in a named: object, for example named: {"year":"2024","month":"03"}, and can be used by name in Replace with.
Why does my pattern match empty strings?
Patterns that can match nothing, such as x* or \d?, succeed with an empty match wherever the next character does not fit. With g ticked, x* on ab reports 3 empty matches, at indexes 0, 1 and 2. Use + instead of * if you need at least one character.
Is JavaScript regex the same as PCRE or Python regex?
Mostly, but not entirely. JavaScript has no possessive quantifiers or atomic groups, sets options with flags rather than a leading (?i), and uses $1 rather than \1 in replacements. Lookbehind is supported in current browsers but was missing from older Safari versions. A pattern that works here works in JavaScript in the same browser; test it in the target language before relying on it elsewhere.
Is my test data sent anywhere?
No. Matching and replacement run in your browser with its own regex engine, and the pattern and text you enter are not sent to a server by the tool. That makes it suitable for testing against log lines or other text you would rather keep private.