Regex explainer and tester
Every token, colour-coded and explained in order. Hover a token or a line to see which is which. Flags where JavaScript and PCRE disagree, and a warning when a pattern can hang on hostile input.
JavaScript ✓PCRE ✓
No catastrophic-backtracking patterns found. (A heuristic check: nested and adjacent repeats, overlapping alternatives.)
^Start of a line (the m flag makes ^ match after every line break)anchor(?<user>…)Named capturing group 'user' (#1)group[\w.+-]One character: a word character: a letter, digit or underscore (A-Z, a-z, 0-9, _), '.', '+' or '-'character class+Repeat the class one or more times, as many as possible (greedy)quantifier@The character '@' literallyliteral(?<domain>…)Named capturing group 'domain' (#2)group[\w-]One character: a word character: a letter, digit or underscore (A-Z, a-z, 0-9, _) or '-'character class+Repeat the class one or more times, as many as possible (greedy)quantifier(?:…)Non-capturing group: groups without rememberinggroup\.The character '.' literallyliteral[\w-]One character: a word character: a letter, digit or underscore (A-Z, a-z, 0-9, _) or '-'character class+Repeat the class one or more times, as many as possible (greedy)quantifier+Then repeat the whole group one or more times, as many as possible (greedy)quantifier$End of a line (the m flag makes $ match before every line break)anchor
2 capturing groups (named: user, domain).
Test it
2 matches
ada@example.com not an email grace.hopper@navy.mil linus@kernel
| # | Match | At | Group 1 | Group 2 |
|---|---|---|---|---|
| 1 | ada@example.com | 0 | ada | example.com |
| 2 | grace.hopper@navy.mil | 29 | grace.hopper | navy.mil |
Regex cheat sheet
| Token | Means | Notes |
|---|---|---|
. | any character except a line break | with s, line breaks too |
\d \w \s | digit, word character, whitespace | capitals negate: \D \W \S |
[abc] [^abc] [a-z] | one of, none of, a range | most metacharacters are literal inside [ ] |
^ $ | start, end | per line with m; PCRE $ also before a final newline |
\b | word boundary | inside [ ] it is a backspace |
* + ? {n,m} | 0+, 1+, 0-1, n to m times | add ? for lazy; PCRE + for possessive |
(…) (?:…) (?<name>…) | capture, group only, named capture | PCRE and Python also accept (?P<name>…) |
\1 \k<name> | the text a group matched | |
a|b | a or b | leftmost alternative that works wins |
(?=…) (?!…) (?<=…) (?<!…) | lookahead, negative lookahead, lookbehind, negative lookbehind | PCRE lookbehind must be bounded length |
(?>…) \A \z \Q…\E | atomic group, string start/end, quoting | PCRE only |
Common patterns, explained
- Regex for an email address
- Regex for an http or https URL
- Regex for an IPv4 address
- Regex for a US phone number
- Regex for a YYYY-MM-DD date
- Regex for a 24-hour time (HH:MM)
- Regex for a hex color code
- Regex for a UUID
- Regex for a strong password (and why length matters more)
- Regex for a URL slug
- Regex to trim leading and trailing whitespace
- Regex for digits only, integers and decimals
- Regex for a semantic version (SemVer)
- Regex for a US ZIP code
- Regex to find repeated words ("the the")
- Regex to match or strip HTML tags
- Greedy vs lazy quantifiers: .* vs .*?
- Catastrophic backtracking, explained with ^(a+)+$