Regex Tester
Test regular expressions against sample text with live match highlighting, per-match capture groups, every flag, and a plain-English explanation of exactly what your pattern matches. 100% in your browser.
Type a pattern (or pick a preset), paste or load sample text, and watch every match light up on the right. Each match shows its position and every capture group it filled. The explainer breaks your pattern down token by token in plain English, so you can see why it matches what it matches — then copy the pattern or export the matches as JSON or CSV.
Pattern
Sample text
The text your pattern is tested against. Paste your own, or load the built-in sample.
Results
Matches
What your pattern matches
| Part of pattern | Plain-English meaning |
|---|
How regular expressions work
A regular expression (regex) is a small pattern language for describing sets of text. Instead of searching for one exact string, you describe the shape of what you want — “three digits, a dash, four digits” — and the engine finds every stretch of text that fits the description. The same pattern that finds a phone number can be tweaked to find a date, an email address or an IP address.
A pattern is read left to right as a sequence of atoms (a literal character, a
character class like \d, or a group), each of which can carry a quantifier
saying how many times it may repeat. Groups let you bundle atoms together and
capture the text they match so you can use it later (here, in the per-match list).
Flags
| Flag | Name | What it does |
|---|---|---|
g | Global | Find all matches in the text, not just the first. Without it, only one match is reported. |
i | Ignore case | a and A are treated as the same character. |
m | Multiline | ^ and $ match the start/end of each line, not just the start/end of the whole text. |
s | DotAll | The dot . also matches line breaks (by default it stops at them). |
u | Unicode | Enables full Unicode support, including \p{...} property escapes and correct handling of multi-code-point characters. |
y | Sticky | Like global, but anchored to the current position — useful when scanning a stream in order. |
Common building blocks
| Token | Matches |
|---|---|
\d / \D | A digit / a non-digit (0-9) |
\w / \W | A word character (letter, digit, _) / anything else |
\s / \S | Whitespace (space, tab, newline) / a non-whitespace character |
. | Any single character except a line break (unless the s flag is on) |
^ / $ | Start / end of the input (or of a line, with the m flag) |
\b | A word boundary — the edge between a word character and a non-word character |
[abc] | Any one of the characters a, b, c |
[a-z] | Any character in the range a to z |
[^a-z] | Any character except those in the class |
x? / x* / x+ | x zero-or-once / zero-or-more / one-or-more times |
x{2,4} | x between 2 and 4 times |
(...) | A group — bundles atoms and captures what they match |
(?:...) | A group that does not capture (lighter, and leaves the group numbers to real captures) |
(?=...) / (?!...) | Lookahead: assert what follows, without consuming it (positive / negative) |
a|b | Alternation: match a or b |
⚠️ Three mistakes that trip everyone up
-
Forgetting
g. Without the global flag the engine stops at the first match. If you expect many matches and only see one, this is almost always the cause. -
Escaping too much (or too little). Characters like
.,*,+,(and?are special. To match a literal one, escape it (\.matches a real dot). Conversely, an unescaped.matches any character, which is a common source of over-matching. -
Greedy vs lazy. Quantifiers are greedy by default —
.*swallows as much as it can. Add?right after (.*?) to make it lazy, so it stops at the first chance. This is the usual fix for “my match is too long”.
Ready-made patterns
The presets above load these patterns. Copy any of them and adapt them to your own data.
| Preset | Pattern |
|---|