Regex explainer
Type or paste a regular expression, bare or as /pattern/flags, and each part of it is explained as you type, in the order the engine reads it. Groups are shown with their contents beneath them, and a pattern that will not compile is refused with the character where it breaks.
^the start of the text (with the m flag, the start of any line)(?<user>[\w.+-]+)group 1, named "user", which captures what it matches[\w.+-]+one or more characters from a word character, ".", "+", or "-", as many as possible\wa word character (a letter, digit, or underscore).a literal ".", since a dot inside brackets has no special meaning+the character "+"-the character "-"@the character "@"(?<domain>[\w-]+\.[a-z]{2,})group 2, named "domain", which captures what it matches[\w-]+one or more characters from a word character or "-", as many as possible\wa word character (a letter, digit, or underscore)-the character "-"\.a literal "."[a-z]{2,}2 or more characters from "a" to "z", in either case, as many as possible$the end of the text (with the m flag, the end of any line)
How to use it#
- Type or paste a regular expression into the box, such as /^\d{3}-\d{4}$/ or \b\w+@\w+\.com\b.
- Read the explanation, one line per part, with the parts inside a group or a class indented under it.
- Tick or clear a flag beside it to see what changes. For a /literal/, the flags after the last slash change with the boxes.
- Copy the explanation if you want it for a code comment or a review.
How the explanation reads#
Each line is one part of the pattern: the text of that part, then what it matches. Plain characters in a row are read as one piece of text, so abc reads as the text "abc" rather than as three lines, and a quantifier is read together with what it repeats, so \d{3} is exactly 3 digits. Anything with parts of its own, a group, a class, or a choice between alternatives, has those parts listed under it, indented one step further, so the indentation follows the brackets of the pattern.
Groups are numbered the way JavaScript numbers them, by the order of their opening brackets, which is the number $1 or \1 uses. Groups that only gather parts together, (?:…), and lookarounds are not numbered, and the Groups figure beside the explanation counts only the ones that capture.
The pattern is checked as it is read. If a bracket is never closed, a quantifier has nothing to repeat, or a range runs backwards, the message names the character where it happens, counted from the start of the box, and says what to change. To see what a pattern matches in your own text, paste both into the regex tester.
What \d, \w, ^, and the other symbols mean#
\d is a digit, 0 to 9, and \D is anything that is not. \w is a letter, digit, or underscore from the basic Latin alphabet, so é is not a word character, and \W is anything else. \s is a space, tab, line break, or other whitespace, and \S is anything else. A dot is any one character except a line break, unless the s flag is on.
^ and $ match a position rather than a character: the start and end of the text, or of each line with the m flag. \b is the edge of a word, the place where a \w character meets one that is not, and \B is anywhere else. None of these uses up any of the text.
[abc] matches one of the characters in it, [a-z] one in a range, and [^abc] one that is not listed. Inside a class, most symbols lose their meaning, so [.] is a plain dot. A backslash before a symbol, such as \. or \(, makes it plain text. The explanation flags a backslash that does nothing, such as the one in \a, which is just the letter a, so a stray escape is easy to spot.
Quantifiers, greedy and lazy#
* is zero or more, + is one or more, and ? is optional. {3} is exactly three, {2,} two or more, and {2,5} between two and five. Each repeats only the one thing just before it, so ab+ is an a followed by one or more b, and repeating the pair takes a group, (?:ab)+.
A quantifier takes as many as it can and gives some back only if the rest of the pattern needs them, which the explanation writes as "as many as possible". A ? after it makes it lazy, taking as few as possible instead: <.+> against <a><b> matches the whole of it, while <.+?> stops at <a>. On a fixed count such as {3}?, the ? changes nothing, and the explanation says so.
A capturing group that repeats keeps only its last repeat. (\d)+ against 123 leaves 3 in group 1, not 123. To capture all of it, put the quantifier inside the group, (\d+).
Groups, lookarounds, and backreferences#
(…) captures what it matches, and (?<name>…) captures it under a name as well as a number. (?:…) groups without capturing, which keeps the numbers of the other groups where they were. (?i:…) turns ignore case on for the group alone, and (?-i:…) turns it off. Only i, m, and s can be set this way, and older browsers do not read it.
Lookarounds check the text beside the current position without taking any of it. (?=…) requires what follows to match and (?!…) requires it not to, while (?<=…) and (?<!…) look at what comes before. \d+(?=px) finds the number in 12px and leaves the px out of the match.
\1 matches the same text group 1 matched, and \k<name> does the same for a named group, so (\w)\1 finds a doubled letter. A reference to a group that has not finished matching yet, such as one that comes before the group, matches an empty string, and the explanation flags it.
What the flags change#
Three flags change what the pattern itself means, and the explanation changes with them. i lets letters match in either case, m makes ^ and $ match at the start and end of every line rather than of the whole text, and s lets a dot match a line break. g, y, and d change how the search runs rather than what a part matches: every match, a match only where the last one ended, and the position of each group.
u and v change how the pattern is read. Without them, JavaScript is forgiving: \a is just a, a ] or { on its own is a character, and an emoji is two halves, so 😀+ repeats only the second half. With u, all of those are errors or are read as whole characters, and \p{…} escapes such as \p{Lu} for an uppercase letter become available. v, unicode sets, adds set operations inside a class and cannot be combined with u: [\p{L}--[a-z]] is any letter except a to z, and [\w&&\p{ASCII}] is a word character that is also ASCII.
Patterns from other languages#
This reads JavaScript regular expressions, which is what browsers, Node.js, and TypeScript run. Most of the syntax is shared with Python, PHP, Java, and .NET, so a pattern from any of them often reads here as it is, but a few constructs are not, and they are refused rather than guessed at.
Python names a group with (?P<name>…), which JavaScript writes as (?<name>…). PCRE, used by PHP, has possessive quantifiers such as a++ and atomic groups, (?>…), which JavaScript has no syntax for. A flag at the very start of a pattern, such as (?i), sets it for the whole pattern elsewhere; JavaScript takes its flags after the closing slash, or as (?i:…) around a part. \A and \Z are written ^ and $ here, and without the u flag \A is read as a plain A, which the explanation points out.
Frequently asked questions#
What do the flags change in the explanation?
#
i, m, and s change what a part matches, so the lines for letters, for ^ and $, and for the dot change as you tick them. u and v change how the whole pattern is read, so a pattern can become an error, or a valid one, when you tick them. g, y, and d change how a search runs and leave the explanation as it is.
Can I paste the pattern with its slashes?
#
Yes. A box that starts with a slash, with another slash later and only flag letters after it, is read as a literal, and its flags tick the boxes beside it. Anything else is read as the pattern itself, so /usr/local is read as a path to match. The Read as figure says which reading was used.
What does \d mean in a regex?
#
\d matches one digit, 0 to 9. \d+ is one or more digits in a row, and \d{3} is exactly three. The capital \D matches any one character that is not a digit. \w and \s work the same way for word characters and whitespace.
What do ^ and $ mean in a regex?
#
^ matches the start of the text and $ the end, so ^\d+$ accepts a string made only of digits. They match positions rather than characters. With the m flag they match at the start and end of every line instead, and ticking it above shows the explanation change.
What do lookahead and lookbehind, ?=, ?!, and ?<=, mean in a regex?
#
They open lookarounds, which check the text beside the current position without including it in the match. (?=…) needs what follows, (?!…) forbids it, (?<=…) needs what comes before, and (?<!…) forbids that. Each is explained with its contents indented beneath it.
What does ?: mean in a regex?
#
(?:…) is a group that does not capture. It gathers its contents into one unit, so a quantifier or a | applies to all of it, without adding a numbered group to the result. (?:https?://)? makes the whole scheme optional, while leaving group 1 for whatever comes after it.
What is the difference between greedy and lazy?
#
A greedy quantifier, the default, takes as much as it can and gives back only what the rest of the pattern needs. A lazy one, written with a ? after it, such as *? or +?, takes as little as it can and takes more only when it has to. Against "a" and "b", the pattern ".+" runs from the first quote to the last, while ".+?" stops at the second quote and matches "a" alone.
Why is my pattern from Python or PHP refused?
#
Because it uses something JavaScript does not have, such as (?P<name>…) from Python, or a possessive quantifier, an atomic group, or a flag like (?i) at the start from PCRE. The message names the character where it stops. Rewrite that part in JavaScript syntax, such as (?<name>…) for a named group, and the rest is explained.
Does it show what my pattern matches?
#
No. This page explains what a pattern means, without running it on any text. To see the matches, the capture groups, and a find and replace on your own text, paste the pattern into the regex tester.