A Test-Matrix Approach to Debugging JavaScript Regular Expressions
A four-axis test-matrix method for debugging JavaScript regex bugs involving Unicode, flags, capture groups, and RegExp state.
A regular expression that works in isolation can still fail inside an application, and the cause is often not the pattern itself but a flag, a Unicode representation mismatch, the consuming API, or mutable RegExp state. Rather than iterating on pattern variants, this approach reframes bugs as a small, executable test matrix across four axes: input, pattern/flags, consumer API, and expected result/state.
Concrete examples show how the u flag shifts matching from UTF-16 code units to Unicode code points, why normalization (NFC/NFD) is a separate data decision that regex flags cannot silently fix, and why optional or repeated capture groups need their own assertions beyond a passing full match. The piece also details how global (g) and sticky (y) flags make RegExp objects stateful — with lastIndex changing across calls — which can cause alternating pass/fail results when a regex instance is reused across requests.
For engineers, the practical takeaway is to stop treating regex bugs as anecdotes and start encoding them as reproducible assertions: pin down the exact input, compare APIs like test, exec, matchAll, and replace deliberately, and treat capture shape and replacement logic as distinct, testable behaviors rather than side effects of a working match.