Regular Expressions
Regular Expressions in JavaScript
Pattern matching, character classes, lookarounds, and named capture groups.
The Master Locksmith Pattern Key
Regular Expressions (RegExp) are patterns used to match character combinations in strings. In JavaScript, RegExps are first-class objects supporting advanced search, validation, and text replacement.
Creating RegExps
Literals (`/pattern/flags`) are compiled at script parse time. Constructors (`new RegExp(pattern, flags)`) are compiled at runtime, ideal for dynamic user inputs.
Core Flags
`g` (global matches), `i` (case-insensitive), `m` (multiline `^` and `$`), `s` (dot matches newlines), `u` (Unicode), `y` (sticky index).
Character Classes and Quantifiers
`\d` (digit), `\w` (alphanumeric + `_`), `\s` (whitespace), `.` (any character). Quantifiers: `*` (0+), `+` (1+), `?` (0 or 1), `{min,max}`.
Named Capture Groups
`(?
Lookahead & Lookbehind Assertions
Positive Lookahead `(?=...)`, Negative Lookahead `(?!...)`, Positive Lookbehind `(?<=...)`, and Negative Lookbehind `(?
Parsing formatted ISO dates using modern named capture groups:
// Matching YYYY-MM-DD with named groups
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = dateRegex.exec("Release date: 2026-09-15");
if (match) {
const { year, month, day } = match.groups;
console.log(`Parsed Year: ${year}, Month: ${month}, Day: ${day}`);
}
// Password strength validation using positive lookaheads
// Must contain at least 1 uppercase, 1 digit, and be >= 8 chars
const strongPassword = /^(?=.*[A-Z])(?=.*\d).{8,}$/;
console.log("Pass 'Secret123':", strongPassword.test("Secret123")); // true
console.log("Pass 'weakpass':", strongPassword.test("weakpass")); // false
Parsed Year: 2026, Month: 09, Day: 15
Pass 'Secret123': true
Pass 'weakpass': false
The Stateful lastIndex Bug with /g Flag
The Risk: When using the global `/g` flag with `regex.test()`, the regex maintains an internal `lastIndex` pointer. Calling `.test()` repeatedly alternates between `true` and `false`!
The Fix: Do NOT use the `/g` flag when simply testing for a match with `.test()`, or reset `regex.lastIndex = 0` manually.
- ✓ `regex.test(str)` returns boolean; `regex.exec(str)` returns match array.
- ✓ `str.matchAll(regex)` returns an iterator of all global matches with capture groups.
-
✓
Named capture groups: `(?
...)` accessible via `match.groups.name`. - ✓ Avoid ReDoS (Regular Expression Denial of Service) by avoiding nested quantifiers like `(a+)+`.
- ✓ Beware of mutable `lastIndex` on global RegExps.