Difficulty: Intermediate
What are advanced RegExp features in JavaScript? Explain named capture groups, lookaheads, and flags.
Modern JavaScript RegExp supports:
Named capture groups: (?<name>pattern) - access matched groups by name
Lookahead/Lookbehind: zero-width assertions that match position without consuming characters: - Positive lookahead: (?=...) - match only if followed by... - Negative lookahead: (?!...) - match only if NOT followed by... - Positive lookbehind: (?<=...) - match only if preceded by... - Negative lookbehind: (?<!...) - match only if NOT preceded by...
Key flags: g (global), i (case-insensitive), m (multiline), s (dotAll), u (Unicode), d (indices)
Non-greedy: *? and +? match as little as possible
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = '2024-03-15'.match(dateRegex);
console.log(match.groups.year);
console.log(match.groups.month);
console.log(match.groups.day);
const { groups: { year, month, day } } = match;
console.log(`${day}/${month}/${year}`);
const reordered = '2024-03-15'.replace(
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/,
'lt;d>/lt;m>/lt;y>'
);
console.log(reordered);
const priceRegex = /\d+(?=€)/;
console.log('100€ and 200#39;.match(priceRegex));
const dollarRegex = /(?<=\$)\d+/;
console.log('$42 and £100'.match(dollarRegex));
Named groups make regex more readable. Lookaheads assert context without including it in the match.
const html = '<div>Hello</div><span>World</span>';
console.log(html.match(/<.+>/)[0]);
console.log(html.match(/<.+?>/)[0]);
const emailRegex = /([\w.-]+@[\w.-]+\.\w+)/g;
const text = 'Contact alice@ex.com or bob@test.org';
const emails = [...text.matchAll(emailRegex)].map(m => m[1]);
console.log(emails);
const multiline = '<tag>\nvalue\n</tag>';
console.log(/<tag>(.*?)<\/tag>/s.exec(multiline)?.[1].trim());
Non-greedy +? stops at the first possible match. matchAll with g flag returns all matches. The s flag makes dot match newlines.
Named Groups, Lookahead, Lookbehind, Flags, Non-greedy