🔍

Regex Tester

Test and debug regular expressions in real-time — with live match highlighting and capture groups.

//g
0 matches
Enter a pattern and test string to see matches.

Regular expressions are the most information-dense mini-language in programming — a dozen characters can express a pattern that would take fifty lines of manual string code — and also the least forgiving, because a regex that is almost right fails silently on the inputs you did not think to try. That combination is why a live tester is the right way to work: you see matches highlight and vanish as you type, which turns regex writing from careful theory into fast experiment. This tester runs your pattern against your sample text in real time, shows capture groups, and supports the standard JavaScript flags.

How the tester works

Type a pattern in the regex field and paste sample text below it. Matches highlight instantly as either changes, and each match's capture groups are listed with their contents. Toggle flags to change behavior: g finds all matches instead of the first, i ignores case, m makes ^ and $ work per-line, and s lets the dot match newlines. The engine is your browser's own JavaScript regex implementation, so behavior exactly matches what the same pattern will do in JavaScript code.

The essential syntax

. any character \d digit \w word char * 0 or more + 1 or more ? 0 or 1 [abc] character set [^abc] negated set ^ start $ end \b word boundary (x) capture group (?:x) non-capturing a|b alternation {2,5} repetition range Email (pragmatic): [\w.+-]+@[\w-]+\.[\w.]+ Date (YYYY-MM-DD): ^\d{4}-\d{2}-\d{2}$

The single most consequential rule: quantifiers are greedy by default. .* takes the longest possible match, so `".*"` applied to a line with two quoted strings matches from the first quote to the last, swallowing everything between. Appending ? makes a quantifier lazy — `".*?"` stops at the first closing quote. Roughly half of all regex bugs in the wild are greedy-versus-lazy mistakes, and the fix is one character.

What to know about regex

  • 1Test against inputs that should not match. A pattern that matches everything you want is half-validated; patterns fail by matching too much far more often than too little. Feed the tester malformed emails, empty strings, and near-miss inputs — the pattern that correctly rejects them is the one that is actually done.
  • 2Escape literal special characters. The characters . * + ? ( ) [ ] { } | ^ $ \ all carry meaning, and forgetting the backslash is the classic silent bug: matching version "1.2" with 1.2 also matches "132", because the dot means any character. When matching a literal dot, write \., always.
  • 3Beware catastrophic backtracking. Nested quantifiers like (a+)+ against a non-matching input can force the engine to try exponentially many paths, freezing the tab — patterns like this have taken down production services. If a pattern hangs on long input, the structure, not the input, is the problem.
  • 4Regex is the wrong tool for nested structures. HTML, JSON, and balanced parentheses require counting depth, which regular expressions mathematically cannot do. Extracting a quick attribute from known HTML is fine; parsing arbitrary HTML with regex is a famous and genuine mistake — use a parser.
  • 5Prefer readable patterns over clever ones. A regex is write-once, read-many like all code, but far denser. Splitting one heroic pattern into two simple steps, or using non-capturing groups (?:) to reduce noise, pays off the first time anyone — including you — must modify it.

Frequently asked questions

Why does my pattern match too much?

Almost always greedy quantifiers. * and + grab the longest match they can, so `".*"` on text with multiple quoted sections matches from the first quote to the very last. Add ? after the quantifier to make it lazy — `".*?"` — and it stops at the earliest completion. Alternatively, use a negated set like `"[^"]*"`, which is often faster and clearer: match anything except a closing quote.

What do the flags g, i, m, and s do?

g (global) finds all matches instead of stopping at the first — without it, replace operations change only one occurrence. i (ignore case) makes letters match both cases. m (multiline) changes ^ and $ from whole-text anchors to per-line anchors. s (dotall) lets . match newline characters, which it otherwise does not — relevant whenever a pattern must span lines.

What is the difference between (x) and (?:x)?

Both group, but (x) captures — the matched text is stored and numbered for extraction or backreference — while (?:x) groups without capturing. Use capturing when you need the contents, non-capturing when you only need grouping for alternation or repetition. Non-capturing keeps group numbers stable and is marginally faster; named groups (?<name>x) are better still when you capture several things.

Is there one correct regex for validating email addresses?

No, and chasing one is a trap. The full RFC grammar for email addresses is famously baroque — the technically complete regex runs to thousands of characters and still cannot confirm a mailbox exists. The pragmatic answer: check the shape with something like [\w.+-]+@[\w-]+\.[\w.]+ and verify deliverability by actually sending a confirmation email. Shape check plus confirmation beats any heroic pattern.

Do regex patterns work the same in every language?

The core is portable, but dialects differ at the edges. This tester uses JavaScript's engine, so lookbehind, named groups, and Unicode classes behave as in modern browsers. Python differs slightly (re.match anchors at the start), grep uses a more limited syntax unless given -P, and Java requires double-escaping backslashes inside string literals. Test in the dialect you will deploy in when using advanced features.