Regex Visual Tester & Match Inspector
Test, debug, and benchmark JavaScript Regular Expressions (RegExp) in real-time with multi-color match highlighting, capture group index inspection, regex substitution playground, and automated ReDoS catastrophic backtracking detection.
$& = match | $1 = group 1
⚠️ 5 Fatal Traps in Regular Expressions (ReDoS & State Bugs)
💥 1. Catastrophic Backtracking (Regular Expression Denial of Service - ReDoS)
Nested quantifiers like (a+)+$ or overlapping groupings cause exponential (O(2^n)) branch evaluations when evaluated against non-matching payloads (e.g., "aaaaaaaaaaaaaaaaaaaaX"). In single-threaded runtimes like Node.js or browser UI threads, a single malicious string locks 100% CPU, freezing the entire application for minutes or hours.
⚖️ 2. The Unescaped Dot in Domain & IP Validation (Security Bypass)
Writing ^192.168.1.1$ or api.stripe.com without escaping the dot (.) allows the dot to match ANY character. An attacker can register api-stripe.com or send 192X168Y1Z1 to bypass origin checks, CORS rules, and SSRF allowlists. Always escape literal dots.
🛡️ 3. The Multiline Newline Blindspot (Missing DotAll / 's' Flag)
Developers frequently assume .* matches all characters across an entire document. In JavaScript, . matches all characters EXCEPT line terminators (
,
). Multi-line inputs silently truncate matching at the first newline unless the s (dotAll) flag or character class [sS]* is specified.
🔍 4. Greedy vs. Lazy Quantifier Collisions (Token Parsing Failure)
Using greedy quantifiers like <.*> to parse HTML/XML tokens matches from the first < to the VERY LAST > on the entire page, gobbling intermediate tags. Use lazy quantifiers (<.*?>) or inverted character sets (<[^>]+>) for deterministic tokenization.
🚀 5. State Leaks in Global Regexes (Mutating 'lastIndex' Bug)
Reusing a global RegExp instance (const re = /pattern/g) across multiple re.test(str) calls causes stateful bugs. Each successful match mutates re.lastIndex forward, causing subsequent tests on identical matching strings to return false! Always reset re.lastIndex = 0 or instantiate fresh regexes per check.