Regex Tester: Debug Your Patterns Without the Guesswork
Regular expressions are powerful and inscrutable. You write one, it doesn't match what you expect, and you spend fifteen minutes staring at a pattern wondering if you need a backslash or a lookbehind.
This tool lets you test regex patterns against sample text in real time. Matches are highlighted inline. Capture groups are displayed in a table. Flags are toggleable. You see exactly what your pattern matches — and what it doesn't — before you commit it to code.
Runs in your browser using JavaScript's native RegExp engine. Nothing leaves your machine.
What's actually happening
The tool compiles your pattern into a JavaScript RegExp object with whatever flags you've selected. It runs matchAll() against your test string and highlights every match directly in the text using <mark> elements.
For each match, it extracts:
- The full match text and its position
- Numbered capture groups (
$1,$2, etc.) - Named capture groups (
(?<name>...))
If your pattern has a syntax error, the tool shows the error message instead of trying to match. No silent failures.
Using it
Type your regex pattern. Paste your test string below it. Toggle flags as needed: g (global), i (case-insensitive), m (multiline), s (dotAll), u (unicode). Matches highlight instantly. Capture groups show in a table below.
When you'd actually reach for this
- You're writing a validation regex and need to test it against both valid and invalid inputs before deploying
- You're parsing log files and building a pattern to extract timestamps, IPs, or error codes
- You're debugging why a regex doesn't match — you can tweak the pattern and see results instantly
- You're learning regex and want to experiment with patterns visually
- You need to extract capture groups and want to verify they're grabbing the right substrings
Regex flags — what each one actually does
g (global) — match all occurrences, not just the first. Without this, the regex stops after the first match. You almost always want this on when testing.
i (case-insensitive) — hello matches Hello, HELLO, and hElLo. Useful for user input where casing varies.
m (multiline) — changes ^ and $ from matching start/end of the entire string to matching start/end of each line. Critical when your test string has newlines and you want per-line anchoring.
s (dotAll) — makes . match newline characters. By default, . matches everything except \n. Enable this when you need . to truly match any character.
u (unicode) — enables full Unicode matching. Without it, . won't match characters outside the Basic Multilingual Plane (like emoji), and \w only matches ASCII word characters. Turn this on for any non-ASCII text.
Common patterns and why they break
Email validation — ^\S+@\S+\.\S+$ catches 99% of valid emails. The "RFC 5322 compliant" regex is 6,000+ characters long and still doesn't catch everything. Don't over-engineer email validation — just check for @ and a dot, then send a confirmation email.
Greedy vs lazy matching — ".*" applied to "hello" and "world" matches the entire substring "hello" and "world" because * is greedy. Use ".*?" for lazy matching to get "hello" and "world" separately.
Catastrophic backtracking — patterns like (a+)+b against a string of as without a trailing b can freeze your browser. The engine tries every possible combination of a+ groupings before giving up. If your regex hangs, simplify nested quantifiers.
Lookbehind support — JavaScript supports lookbehind ((?<=...) and (?<!...)) in modern browsers, but older environments don't. If you're targeting Node 8 or IE, lookbehinds won't work.
Troubleshooting
My pattern matches in another tool but not here — different regex engines have different syntax. Python's re module, PCRE (used by PHP/Perl), and JavaScript's RegExp are not identical. Named groups in Python use (?P<name>...) while JavaScript uses (?<name>...). Check engine-specific syntax.
Matches highlight but the capture group table is empty — your pattern has no capture groups. Parentheses create groups: (\d+) captures digits. If you're using non-capturing groups (?:...), they won't appear in the table.
The pattern shows an error but it looks correct — JavaScript regex syntax has specific rules. Common issues: unescaped { or } (needs \{), invalid quantifier like {,3} (needs {0,3}), or unsupported syntax for your browser.
I can't match across lines — by default, . doesn't match \n. Enable the s flag. Or use [\s\S] as a portable "match anything including newlines" pattern that works everywhere.
My pattern matches too much — you're probably using greedy quantifiers. Switch * to *?, + to +?, or use more specific character classes instead of ..
What to do with the result
Once your pattern works, copy it into your code. Remember to double-escape backslashes in string-based regex constructors — new RegExp("\\d+") in JavaScript, not new RegExp("\d+"). Using regex literals (/\d+/g) avoids this issue.
Test edge cases: empty strings, strings with only whitespace, extremely long input, and Unicode characters. The pattern that works on your three test cases might break on real-world data.