Regex Tester & Debugger
Test regular expressions with live match highlighting, capture groups, replace mode, and a full cheatsheet — all in your browser.
Ready-to-Use Regex Snippets
Click any snippet to load it directly into the tester. All patterns are production-tested.
Regex Cheatsheet
Every token you need — from basic anchors to advanced lookarounds.
How to Use This Tool
Everything the regex tester does and how to get the most out of each feature.
$1, $2, etc. — the same references you use in replace operations.$1, $2, $& to reference groups and the full match. The replaced output appears below.What's Built In
A full regex workbench — no extensions, no sign-up, nothing sent to a server.
$1 $2 $& references. See the substituted result instantly.Frequently Asked Questions
Common questions about regex and how this tester works.
This tool uses the JavaScript RegExp engine built directly into your browser. It supports all standard JavaScript regex features including lookahead, lookbehind (in modern engines), named capture groups ((?<name>...)), and the g, i, m, s, u, and y flags. The engine is the same one used by String.prototype.match() and String.prototype.replace() in your JavaScript code.
The g flag is on by default in this tool because most people testing regex want to see all matches in a body of text, not just the first one. Without g, regex.exec() and string.match() stop at the first match. Toggling it off is useful when you specifically want to test that a pattern matches exactly once or to measure first-match behaviour.
Wrap part of your pattern in parentheses to create a capture group. For example, (\d{4})-(\d{2})-(\d{2}) creates three groups for year, month, and day. Each match in the results panel shows the captured values as colour-coded pills labelled $1, $2, $3. In replace mode, reference groups with those same labels: replacing (\d{4})-(\d{2})-(\d{2}) with $3/$2/$1 converts ISO dates to DD/MM/YYYY.
Greedy quantifiers (*, +, {n,m}) consume as many characters as possible while still allowing the overall pattern to match. Lazy quantifiers (*?, +?, {n,m}?) consume as few as possible. For example, against <b>bold</b>, the pattern <.*> (greedy) matches the entire string in one match, while <.*?> (lazy) matches <b> and </b> separately. Use lazy matching when parsing HTML-like or nested content.
A lookahead asserts that what follows the current position matches (or doesn't match) a pattern, without consuming characters. (?=abc) is a positive lookahead — "match if followed by abc". (?!abc) is negative — "match if NOT followed by abc". Lookbehinds ((?<=...)) work the same way but look backwards. Use lookarounds when you need to validate context around a match without including that context in the captured result — for example, \d+(?= dollars) matches a number only if the word "dollars" follows it.
Over-matching is usually caused by: (1) greedy quantifiers — try adding ? after * or + to make them lazy; (2) missing anchors — add ^ and $ to enforce a full-string match; (3) . matching more than intended — use a character class like [^,\n] instead to stop at delimiters; (4) missing boundaries — add \b around word patterns to prevent partial word matches.
Escape the character with a backslash: \. matches a literal dot, \[ and \] match brackets, \( and \) match parentheses, \* matches an asterisk. In a JavaScript string, you need a double backslash because the string parser consumes one: new RegExp('\\.'). In a regex literal /\./ you only need one backslash.
Catastrophic backtracking (ReDoS) happens when a regex with nested quantifiers — like (a+)+ — takes exponential time on certain inputs because the engine retries enormous numbers of possible match paths. It can freeze a browser tab or crash a Node.js server. Prevention: avoid nested quantifiers, use possessive quantifiers or atomic groups if the engine supports them, prefer specific character classes over broad ones, and test patterns against adversarial inputs before deploying to production.
Enable the m (multiline) flag — this makes ^ and $ match the start and end of each line, not just the entire string. To match content that spans lines (e.g. a block comment), you also need the s (dotall) flag so . matches newline characters. For example, /\/\*.*?\*\//gs matches /* ... */ comments even when they span multiple lines.
This tool uses the JavaScript regex engine, which is largely compatible with Python re and PHP preg for common patterns. Key differences: Python supports \A and \Z as string anchors; PHP defaults to PCRE which supports possessive quantifiers and atomic groups; Python doesn't have the s flag — use re.DOTALL instead. For complex patterns targeting non-JavaScript environments, verify the final result in the actual runtime.