A regular expression, or regex, is a pattern that describes text: "a run of digits", "an email address", "a word that ends in ing". This tester runs your pattern against your text as you type and shows what matched, what each capture group caught, and what a find and replace would produce. It uses JavaScript's regular expressions, the same engine as your browser.
JavaScript regular expressions, the same engine your browser runs. Other languages differ in places.
Flags
Matches
2 matches
Contact ada@example.com or grace@navy.mil for access. Ignore not-an-email and @nobody.
| # | Match | Groups |
|---|---|---|
| 1 | ada@example.comat 8, length 15 |
|
| 2 | grace@navy.milat 27, length 14 |
|
Replace
$1 and $<name> insert a group, $& the whole match. Without the g flag only the first match is replaced.
Result
Contact example.com: ada or navy.mil: grace for access. Ignore not-an-email and @nobody.
As a JavaScript literal
/(?<user>[\w.]+)@(?<host>[\w-]+\.\w+)/gQuick reference
Characters
- .
- Any character except a newline (add the s flag to include it)
- \d \D
- A digit, or anything but a digit
- \w \W
- A letter, digit or underscore, or anything else
- \s \S
- Whitespace, or anything but
- [abc]
- One of a, b or c
- [^abc]
- Anything except a, b or c
- [a-z]
- One character in a range
- \p{L}
- A letter in any language (needs the u or v flag)
Anchors
- ^ $
- Start and end of the text (of each line with the m flag)
- \b \B
- A word boundary, or not one
Quantifiers
- * + ?
- 0 or more, 1 or more, 0 or 1
- {3} {3,} {3,5}
- Exactly 3, at least 3, 3 to 5
- *? +? ??
- Lazy: as few as possible
Groups and alternatives
- (abc)
- Capture group, numbered from 1
- (?<name>abc)
- Named capture group
- (?:abc)
- Group without capturing
- a|b
- a or b
- \1 \k<name>
- Match the same text as a group did
Lookaround
- (?=abc) (?!abc)
- Followed by, or not followed by
- (?<=abc) (?<!abc)
- Preceded by, or not preceded by
In the replacement
- $1 $<name>
- The text a numbered or named group captured
- $& $$
- The whole match, or a literal dollar sign
The full list, with tested examples: the Regex cheat sheet.
Matched in your browser, in a background worker that is stopped after 2 seconds. Nothing you type is uploaded or stored.
Type a pattern in the top box, choose its flags, and paste the text to search. Every match is highlighted in the text and listed in a table with its position and groups. Under it, the Replace box shows the text after the replacement. Quick reference at the bottom lists the tokens people look up most.
How to use it
- Type a pattern without the slashes around it.
\d+is a run of digits. - Turn on the flags you need. g finds every match, i ignores case.
- Paste the text to search. Highlighted stretches are the matches, and two matches next to each other alternate colours so you can tell them apart.
- Read the table. The Groups column shows
$1,$2and so on for the numbered groups, and<name>for the named ones. A group that did not take part in the match, such as an optional one, says so. - Type a replacement such as
$2, $1to preview a find and replace, then tap Copy to take the result, or copy the finished regex as a JavaScript literal.
An invalid pattern shows the engine's own error, for example Invalid regular expression: /(/: Unterminated group, which is the message you would get in
your console.
The flags
| Flag | Name | What it changes |
|---|---|---|
g | global | Finds every match. Without it only the first is reported and replaced |
i | ignore case | A and a match each other |
m | multiline | ^ and $ match at each line, not only the start and end of the text |
s | dot all | . also matches a newline |
u | unicode | Reads the pattern as code points, so . matches an emoji as one character, and allows \p{L} |
v | unicode sets | Like u, plus set operations such as [\p{L}--[a-z]]. Not combinable with u |
y | sticky | A match has to start exactly where the previous one ended |
Why a pattern can freeze a page, and how this one does not
Most regex engines, JavaScript's included, find a match by trying one route
through the pattern and backing up to try another when it fails. For most
patterns that costs almost nothing. A few take an exponential amount of time
when the text does not match. The classic is (a+)+$ against
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!: every extra a doubles the work, and a regex
that is running cannot be interrupted by the page.
That is called catastrophic backtracking, and it is behind real outages when a user-supplied string meets a careless pattern on a server. In a tester it would freeze the tab. So this one runs the matching in a Web Worker, a separate thread. If the worker has not answered after 2 seconds the tester stops it, tells you, and starts a fresh one for your next edit. Your page stays responsive the whole time.
To fix a pattern that times out:
- Remove a quantifier from inside a group that is itself repeated:
(a+)+becomesa+. - Replace a broad
.*with a narrower class such as[^,]*, so the engine has fewer places to back up to. - Anchor the pattern with
^where it should only match from the start.
Empty matches
A pattern can match zero characters. a* against baaac finds an empty match
before the b, aaa, and empty matches before the c and at the end of the
text. The tester marks an empty match with a thin pink bar and lists it as
empty match. After each one it moves on by a character, so a* cannot loop on
the same spot. With the u or v flag it steps over a whole emoji at once.
Replacing with groups
The replacement is JavaScript's, as in string.replace(regex, replacement):
| In the replacement | Inserts |
|---|---|
$1, $2, ... | The text numbered group 1, 2, ... captured |
$<name> | The text the named group (?<name>...) captured |
$& | The whole match |
$` and $' | The text before and after the match |
$$ | A literal dollar sign |
A group that did not take part gives an empty string. A $1 with no group 1 in
the pattern stays as the literal characters $1. Leave the replacement empty to
delete every match.
Common gotchas
- Escaping in code is different from escaping here. Type
\d+in the box. In a JavaScript string passed tonew RegExpyou write"\\d+", because the string needs its own backslash. The JavaScript literal line under the result shows the pattern written the way code needs it. - Other languages are not the same. Named groups are
(?P<name>...)in Python, lookbehind has limits in some engines, and PCRE has features that JavaScript does not, such as possessive quantifiers and recursion. Check the pattern in the language you will use. .does not match a newline unless you turn on thesflag, and^and$match only the start and end of all the text unless you turn onm.\wis ASCII only. It does not matchéorñeven with theuflag. Use\p{L}withuorvfor letters in any language.- Greedy against lazy.
<.+>takes everything from the first<to the last>.<.+?>stops at the first>. - Validating an email or URL is harder than it looks. A short pattern is fine for "does this look roughly like an email". It cannot tell you the address exists.
Related
- The Regex cheat sheet for every token, with
tested examples, and the JavaScript cheat
sheet for
match,matchAll,replaceandreplaceAll. - Diff Checker to compare a string before and after a replacement, line by line.
- Case Converter and Word Counter for text jobs that do not need a pattern.
- Cron Expression Generator for another small pattern language worth testing before you ship it.
Common questions
What is a regex tester?
A regex tester runs a regular expression against some text and shows you what it matched, so you can get a pattern right before it goes into code. This one highlights every match, lists each match with its capture groups, and previews a find and replace. It uses JavaScript's own regular expression engine, so a pattern that works here works in a browser or Node.js.
Which regex flavour does this tester use?
JavaScript, also called ECMAScript. It runs the same engine as your browser, so the syntax and the error messages are JavaScript's. Python, PCRE (PHP and many editors), Java and .NET are close but not identical: lookbehind, named group syntax, possessive quantifiers and inline flags differ. Test the pattern in the language you will run it in before you rely on it.
Why did it say the pattern was stopped after 2 seconds?
The pattern is backtracking badly. A regex engine that cannot match tries every other way of splitting up the text before it gives up, and a nested quantifier such as (a+)+$ gives it an exponential number of ways. The tester runs patterns in a background worker and stops it after 2 seconds, so the page never freezes. Make the pattern more specific, remove the nested quantifier, or shorten the text.
How do I use a capture group in the replacement?
Write $1, $2 and so on for the numbered groups, or $<name> for a named group, in the Replace box. $& is the whole match and $$ is a literal dollar sign. For example, replacing (\w+)@(\w+) with $2 at $1 turns ada@example into example at ada.
What do the regex flags g, i, m, s, u, v and y do?
g finds every match instead of just the first. i ignores case. m makes ^ and $ match at the start and end of each line. s lets the dot match a newline. u reads the pattern as Unicode and allows \p{...} classes. v is the newer Unicode mode with set operations in character classes, and it cannot be combined with u. y only matches at the exact position where the last match ended.
Why does my regex find only one match?
Without the g flag, JavaScript stops at the first match. Turn on the g flag, shown as a button under the pattern, to find them all. The replace preview works the same way: without g only the first match is replaced.
Does the tester handle empty matches?
Yes. A pattern like a* can match zero characters, for example between letters. The tester marks each empty match with a thin bar and moves on by one character, or by one whole emoji or other character outside the basic plane when the u or v flag is on, so it never loops on the same spot.
Is anything I enter here sent to a server?
No. The pattern runs in your browser, in a Web Worker, and nothing you type is submitted anywhere. The site records that the tool was used, the flags you had on and how many matches there were, so we know which tools are worth building next. The pattern, the text and the replacement are never part of that.