はじめに
ES2024で導入された vフラグは、JavaScriptの正規表現に大きな進化をもたらしました。従来のuフラグの上位互換であり、文字クラスの集合演算(差分・共通部分)、入れ子の文字クラス、そして絵文字の正確なマッチングを可能にします。
vフラグとは
vフラグを有効にするには、正規表現の末尾にvを追加します:
const re = /[\p{Letter}]/v;
vモードでは文字クラスを集合として扱い、ブール演算で組み合わせられます。uフラグでは不可能だった高度なパターンが記述可能になりました。
文字クラスの差分(Subtraction)
待望の機能が、ある文字クラスから別の文字クラスを差し引く演算です。-- 演算子を使います:
// 母音以外のすべての文字
const re = /[\p{Letter}--[aeiouAEIOU]]/v;
console.log(re.test('b')); // true
console.log(re.test('a')); // false
これは「すべてのUnicode文字からASCII母音を除いた集合」を意味します。
文字クラスの共通部分(Intersection)
&&演算子で二つの集合の共通部分を取得できます:
// ギリシャ文字のみにマッチ
const re = /[\p{Letter}&&\p{Script=Greek}]/v;
console.log(re.test('α')); // true
console.log(re.test('a')); // false
差分と共通部分を組み合わせれば、極めて精緻なパターンが書けます:
// ギリシャ文字から「α」を除く
const re = /[[\p{Letter}&&\p{Script=Greek}]--[α]]/v;
入れ子の文字クラス
vフラグでは文字クラスの中にさらに文字クラスを入れ子にできます。従来のエスケープ地獄から解放されます:
// uフラグ — わかりにくい
const re1 = /[a-z&&[^aeiou]]/u;
// vフラグ — 直感的
const re2 = /[[a-z]--[aeiou]]/v;
絵文字の正確なマッチング
絵文字のマッチングは従来非常に困難でした。vフラグは \p{RGI_Emoji} をはじめとする新しいUnicodeプロパティを提供します:
// 複数コードポイントからなる絵文字も1つとしてマッチ
const re = /\p{RGI_Emoji}/v;
console.log(re.test('😀')); // true
console.log(re.test('👨👩👧👦')); // true(家族絵文字)
console.log(re.test('a')); // false
新しい絵文字関連プロパティ:
| プロパティ | 説明 |
|---|---|
\p{Basic_Emoji} | 単一コードポイントの絵文字 |
\p{Emoji_Keycap_Sequence} | #️⃣ などのキーキャップ |
\p{RGI_Emoji_Flag_Sequence} | 🇯🇵 などの国旗 |
\p{RGI_Emoji_Modifier_Sequence} | 肌色バリエーション |
uフラグからの移行と注意点
vフラグはuの上位互換ですが、破壊的な変更もあります:
| 項目 | uフラグ | vフラグ |
|---|---|---|
文字クラス内の\d | リテラル\d | エラー(\\dとエスケープが必要) |
[ の扱い | リテラル | 入れ子開始 |
-- | ハイフン2つ | 減算演算子 |
&& | アンパサンド2つ | 積集合演算子 |
サポート状況とまとめ
vフラグはChrome 125+、Firefox 127+、Safari 17.5+、Node.js 22+で利用可能です。機能検出は次のように行えます:
const supportsV = (() => {
try { return new RegExp('', 'v') !== null; } catch { return false; }
})();
vフラグは正規表現を単なるパターンマッチから集合処理言語へと進化させました。複雑な文字クラス処理や絵文字マッチングが必要な場合、積極的に採用しましょう。
