Skip to content

Regex Explainer

Breaks a regular expression into a labelled tree so you can read what each part actually matches.

Breaks a regular expression into a tree and says what each piece does — every group, quantifier, class and assertion, nested the way the pattern is. It is the same screen as the tester, opened on its explain tab, because reading a pattern and running it are the same activity.

🔒 Runs entirely in your browserregexexplainlearn
View

Pattern

//g

can match anywhere in the string, 2 capture groups.

What each part does

([\w.+-]+)@([\w-]+\.[\w.-]+)In order

Each of these must match, one after another, with nothing between them.

([\w.+-]+)Capture group 1

Matches the pattern inside and remembers the text, available as `match[1]` and as `$1` in a replacement.

[\w.+-]+Repeated +

Repeat one or more times, as many as possible, giving back only when the rest fails.

[\w.+-]Any one character from this set

Matches exactly one character, whichever of the following comes first in the input.

Inside a class, `.` is a full stop. It does not mean "any character" here, and escaping it changes nothing.

\wAny word character

Exactly `[A-Za-z0-9_]`.

This is ASCII-only. `é`, `한` and `ß` are not word characters to a JavaScript regex, so `\w+` will not match a Korean or accented word.

.The character “.” (U+002E)

Matched exactly, including case.

+The character “+” (U+002B)

Matched exactly, including case.

-The character “-” (U+002D)

Matched exactly, including case.

@The character “@” (U+0040)

Matched exactly, including case.

([\w-]+\.[\w.-]+)Capture group 2

Matches the pattern inside and remembers the text, available as `match[2]` and as `$2` in a replacement.

[\w-]+\.[\w.-]+In order

Each of these must match, one after another, with nothing between them.

[\w-]+Repeated +

Repeat one or more times, as many as possible, giving back only when the rest fails.

[\w-]Any one character from this set

Matches exactly one character, whichever of the following comes first in the input.

\wAny word character

Exactly `[A-Za-z0-9_]`.

This is ASCII-only. `é`, `한` and `ß` are not word characters to a JavaScript regex, so `\w+` will not match a Korean or accented word.

-The character “-” (U+002D)

Matched exactly, including case.

\.The character “.” (U+002E)

Matched exactly, including case.

The backslash is redundant here — this character has no special meaning at this position.

[\w.-]+Repeated +

Repeat one or more times, as many as possible, giving back only when the rest fails.

[\w.-]Any one character from this set

Matches exactly one character, whichever of the following comes first in the input.

Inside a class, `.` is a full stop. It does not mean "any character" here, and escaping it changes nothing.

\wAny word character

Exactly `[A-Za-z0-9_]`.

This is ASCII-only. `é`, `한` and `ß` are not word characters to a JavaScript regex, so `\w+` will not match a Korean or accented word.

.The character “.” (U+002E)

Matched exactly, including case.

-The character “-” (U+002D)

Matched exactly, including case.

Flags

g — global
Finds every match rather than stopping at the first. `.test()` and `.exec()` then advance `lastIndex` between calls, which is the usual source of "every other call fails".

How to use it

  1. Paste the pattern you inherited

    The one in the config file that nobody remembers writing. It is parsed rather than pattern-matched, so the breakdown follows the real structure.

  2. Read down the tree

    Each node shows the source fragment, what it is, and what it does. Notes flag the parts that commonly surprise people — a nested quantifier, a group that captures when it did not need to.

  3. Switch to Test to check your reading

    The pattern carries across. Understanding a regex and confirming it does what you think are two different steps, and the second one is the cheap one.

Common questions

What does the warning on a nested quantifier mean?

Something like `(a+)+` gives the engine exponentially many ways to split the same text, so a non-matching input can take longer than the age of the universe. It is the shape behind most regular-expression denial of service.

Why does it tell me a group is capturing?

Because a capturing group you do not use costs a slot and shifts the numbering of the ones you do. `(?:…)` groups without capturing, which keeps `$1` pointing at what you meant.

Does it explain flags too?

Yes, in a panel of their own — each flag you have set, its name, and what it changes. `m` and `s` in particular are worth reading, because their names suggest each other’s behaviour.

Feed it from

Next

These accept what this tool produces, so the result can go straight in.