← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · ✎ updated 7d
← Back to glossary

Regular Expressions in JavaScript

JavaScript ES2015 Intermediate
debt(d6/e3/b3/t8)
d6 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5), but slightly worse. ESLint and Semgrep can catch obvious patterns (missing /u flag, g flag in loops), but ReDoS vulnerabilities and subtle Unicode mismatches often slip through automated detection without specialized regex analysis tools. Runtime testing is frequently needed to surface stateful lastIndex bugs. Score d6 reflects that common cases are caught by linters, but many regex-specific hazards require careful manual review.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix guidance (add /u flag, use named capture groups, test patterns) is straightforward within a single regex or small group of regexes. Fixing test() with g flag loops or match() without g is a one-file refactor. However, fixing widespread ReDoS vulnerabilities or Unicode handling across multiple regexes may require more care, keeping it solidly at e3 rather than e1.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Regex choices are typically contained within individual functions or string-matching utilities. They do not impose system-wide architectural constraints (unlike custom auth or shared mutable state). However, if a codebase adopts a convention around regex flags or named capture groups, that becomes a light productivity tax on all future pattern authors. Score b3 reflects that the burden is local to regex-heavy components, not cross-cutting.

t8 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7), verging on t8. The canonical misconception (JS regex behaves like PCRE, and g flag test() is stateless) directly contradicts how similar concepts work in other languages. The stateful lastIndex behaviour is non-obvious and causes alternating true/false in loops—a famous gotcha. Unicode handling without /u silently fails on non-ASCII input. These are not one-off edge cases but systematic misunderstandings that catch competent developers regularly. Score t8 reflects that the obvious way (test() in a loop, no flags) is often wrong, and the trap is deeply rooted in language design.

About DEBT scoring →

Also Known As

JavaScript regex RegExp regular expression JS

TL;DR

JS regex syntax, flags (g, i, m, s, u, d), methods (test, match, matchAll, replace, split), and the critical differences from PHP's PCRE.

Explanation

JS regex: /pattern/flags or new RegExp(pattern, flags). Key methods: test() (returns boolean), match() (returns array or null), matchAll() (returns iterator of all matches — requires g flag), replace()/replaceAll() (string replacement), split() (split by pattern). Flags: g (global — all matches), i (case-insensitive), m (multiline — ^ and $ match line boundaries), s (dotAll — . matches newlines), u (Unicode — enables \u{1F600} and correct Unicode handling), d (indices — adds match index info). Named capture groups: (?<name>pattern). Lookahead: (?=) positive, (?!) negative.

Common Misconception

✗ JavaScript regex is the same as PHP PCRE — JS regex lacks some PCRE features (no lookbehind in older engines, no \K, different flag syntax), and the g flag with test() has a stateful lastIndex that causes surprising behaviour.

Why It Matters

The stateful g flag with RegExp.test() in a loop is a famous JS gotcha — test() advances lastIndex on each call, causing alternating true/false for a pattern that should always match.

Common Mistakes

  • Using RegExp.test() with g flag in a loop — lastIndex advances causing false negatives.
  • Not using the u flag for Unicode strings — \w does not match accented characters without u.
  • match() without g flag returns only first match — use matchAll() for all matches.
  • Not anchoring patterns — /cat/ matches concatenate, not just the word cat.

Code Examples

✗ Vulnerable
// Stateful g flag bug — alternating results:
const re = /hello/g; // g flag makes lastIndex stateful
console.log(re.test('hello world')); // true  (lastIndex=5)
console.log(re.test('hello world')); // false (lastIndex=0 after miss)
console.log(re.test('hello world')); // true  (lastIndex=5 again)

// match() only returns first:
'aaa'.match(/a/);  // ['a'] — not all three!
✓ Fixed
// Avoid g flag with test() — or reset lastIndex:
const hasHello = /hello/.test('hello world'); // No g — safe

// matchAll for all matches:
const matches = [...'aaa'.matchAll(/a/g)]; // [{...}, {...}, {...}]

// Named capture groups:
const dateRe = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const { groups: { year, month, day } } = '2026-03-16'.match(dateRe);

Added 16 Mar 2026
Edited 22 Mar 2026
Views 129
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping S 1 ping M 1 ping T 1 ping W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 2 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M
No pings yet today
No pings yesterday
Amazonbot 16 PetalBot 12 ChatGPT 8 SEMrush 8 Ahrefs 7 Google 5 Perplexity 4 Bing 3 Brave Search 3 Majestic 2 Claude 2 Scrapy 2 Applebot 2 Unknown AI 2 Meta AI 1 Twitter/X 1
crawler 72 crawler_json 6
🧱 FUNDAMENTALS — new to this? Start with the ground floor.
JavaScript javascript The programming language of the browser — it reads and modifies the page (the DOM), reacts to user events, and fetches data without reloading.

JavaScript is the only language browsers execute, so every interactive behaviour on the web goes through it. Its two defining traits — single-threaded event loop and loose typing (== coercion) — explain the majority of both its bugs and its design patterns.

💡 Default to const, use === always, and reach for let only when a value genuinely reassigns.

Ask Codex about JavaScript →
⚡ DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Add the /u flag to all regexes matching user text to enable Unicode mode; use named capture groups (?<year>\d{4}) for readable matches; test with online tools before production
📦 Applies To
javascript ES2015 web cli
🔗 Prerequisites
🔍 Detection Hints
Regex without /u flag on user-input text with Unicode; regex ReDoS vulnerability exponential backtracking; no named capture groups in complex patterns
Auto-detectable: ✓ Yes eslint semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: Line
CWE-400


✓ schema.org compliant