JavaScript RegExp v Flag: Set Notation & Properties
The JavaScript RegExp v (unicodeSets) flag modernizes
regular expressions by upgrading the capabilities of the existing
u flag to support advanced set operations and
multi-code-point Unicode properties. Introduced in ECMAScript 2024, this
feature allows developers to perform set intersections, subtractions,
and unions directly within character classes, while also enabling
character classes to match sequences of characters such as complex
emojis. By introducing these features, the v flag
eliminates the need for complex lookaheads and manual string splitting,
making pattern matching in modern JavaScript more expressive, reliable,
and readable.
Set Operations: Intersection, Subtraction, and Union
Prior to the v flag, character classes
([...]) were limited to simple unions. The v
flag introduces explicit set operations directly inside character
classes using double operators:
Intersection (
&&): Matches characters that exist in both specified sets.// Matches Greek letters that are also uppercase const greekUpper = /[\p{Script=Greek}&&\p{Uppercase}]/v; greekUpper.test('Ω'); // true greekUpper.test('ω'); // falseSubtraction (
--): Removes characters in the second set from the first set.// Matches any decimal digit except ASCII 0-9 const nonAsciiDigits = /[\p{Decimal_Number}--[0-9]]/v; nonAsciiDigits.test('٣'); // true (Arabic-Indic digit 3) nonAsciiDigits.test('3'); // falseNested Character Classes: Classes can be nested within each other to combine different operations cleanly.
// Matches ASCII letters, except vowels const consonants = /[[a-z]--[aeiou]]/iv; consonants.test('b'); // true consonants.test('e'); // false
Properties of Strings
Under the older u flag, Unicode property escapes
(\p{...}) could only match individual code points. The
v flag introduces “properties of strings,” allowing a
single property escape inside a character class to match
multi-code-point sequences.
This is particularly useful for emojis composed of multiple Unicode code points (such as flag sequences, skin tone modifiers, and zero-width joiner sequences):
// Matches any valid emoji, including complex multi-character sequences
const emojiRegex = /^\p{RGI_Emoji}$/v;
emojiRegex.test('⚽'); // true (single code point)
emojiRegex.test('👨👩👧👦'); // true (multi-code-point sequence joined by ZWJ)
emojiRegex.test('🇨🇦'); // true (flag sequence of two regional indicators)Without the v flag, matching multi-character emoji
sequences required verbose regular expressions or manual
tokenization.
String Literals in Character Classes
The v flag allows explicit string literals inside
character classes using the \q{...} syntax. This makes it
possible to treat whole words or character sequences as single elements
within a set:
// Matches standard digits or the written-out words "one", "two", "three"
const digitOrWord = /[\d|\q{one|two|three}]/v;
digitOrWord.test('5'); // true
digitOrWord.test('two'); // trueStricter Parsing and Compatibility
The v flag enforces stricter syntax rules compared to
older flags to avoid ambiguity with the new operator syntax:
- Characters with special meanings in set operations (
(,),[,],{,},/,-,\,&,|,!,#,$,%,*,+,,,.,:,;,<,=,>,?,@,^,`,~) must be escaped when used as literals inside[...]. - The
vflag is mutually exclusive with theuflag (/pattern/uvthrows aSyntaxError). However, thevflag includes all existinguflag features by default, making it a complete replacement foru.