Regex Tester

Test a regular expression live — with match highlighting, capture groups and a plain-English breakdown.

3 matches ✓global — find every match, not just the first · ignore case
Test string
Matches
Reply to [email protected] or [email protected].
Old address (bounces): [email protected].org
Not an address: @nobody, plain.text, mailto:
Matches & capture groups
#AtMatch1 · user2 · domain
19[email protected]adaexample.com
228[email protected]Grace.Hopper+navynavy.mil
379[email protected]timberners-lee.example
What this pattern says
  1. (?<user>start of capture group 1, named "user"
  2. [\w.+-]any one character from any word character — a letter, digit or underscore, ".", "+", "-"
  3. +repeat the previous item one or more times
  4. )end of the group
  5. @the character "@"
  6. (?<domain>start of capture group 2, named "domain"
  7. [\w-]any one character from any word character — a letter, digit or underscore, "-"
  8. +repeat the previous item one or more times
  9. \.the character ".", treated literally
  10. [a-z]any one character from a to z
  11. {2,}repeat the previous item 2 or more times
  12. )end of the group
3
Matches
2
Groups
152
Characters

How to use the regex tester

Type your pattern between the slashes, switch flags on with the letter buttons, and paste the text you want to test underneath. Everything updates as you type: matches are highlighted in the preview, every match and capture group is listed in the table, and the breakdown at the bottom translates your pattern into plain English, one piece at a time. That last panel is the point of this page — most testers show you *that* something matched, not *why*.

What the flags actually do

Flags change how the whole pattern is applied. The two that surprise people most are g and m: without g you only ever get the first match, and ^ and $ mean "start and end of the entire text" until m turns them into line anchors.

g — globalFind every match, not just the first
i — ignore caseTreat A and a as the same
m — multiline^ and $ match at every line break
s — dotall. also matches newline characters
u — unicodeFull code-point matching, enables \p{…}
y — stickyMatch only at the current position

Capture groups, named and numbered

Parentheses capture: (\d{4}) stores whatever the four digits matched as group 1, and you can name it instead with (?<year>\d{4}). Named groups are far easier to read six months later, and they survive re-ordering — group numbers do not. If you only need parentheses for grouping, use (?:…) so the engine does not store anything.

Catastrophic backtracking, and why this page caps things

Some patterns are exponentially slow on input that nearly matches. The classic shape is a repeat inside a repeat — (a+)+$ against a long run of "a" followed by "b" — where the engine tries every possible split before giving up. This is a real denial-of-service class (ReDoS) when the pattern runs on a server against user input. The tester warns when it spots that shape, caps the test string, caps the match count, and stops long match loops. Be honest about the limit though: a JavaScript regex cannot be interrupted mid-match, so a truly catastrophic pattern can still freeze the tab until it finishes. If that happens, reload — nothing was saved, and nothing was sent anywhere.

  • Prefer a specific character class over . — [^"]* instead of .*
  • Avoid nesting unbounded repeats: (a+)+ and (.*)* are the danger signs
  • Anchor with ^ and $ so failures are found early
  • Make repeats lazy (*?) when you want the shortest match, not the longest

Frequently asked questions

Is my pattern or test text sent anywhere?

No. The pattern is compiled and run by your own browser's regex engine, in this tab. Nothing you type is stored or transmitted.

Which regex flavour is this?

JavaScript (ECMAScript) — the same engine your browser uses. It is very close to PCRE for everyday patterns, but not identical: there are no possessive quantifiers or atomic groups, and lookbehind support depends on your browser. A pattern that works here will work in Node and in the browser; PHP, Python or Go may differ in the corners.

Why does my pattern match nothing when it works elsewhere?

Usually one of three things: the g flag is off so you only get the first match, the pattern was copied with its surrounding slashes and flags included (paste only the part between them), or a backslash was lost in copying — \d became d.