このコンテンツはまだ翻訳されていません。 翻訳に協力してください

ユニコードフラグ

ユニコードフラグ /.../u はサロゲートペアの正しいサポートができるようになります。

サロゲートペアについては、チャプター 文字列 で説明されています。

簡単に思い出してみましょう。手短に言えば、通常の文字は2バイトでエンコードされています。それは最大で 65536 文字になります。しかし世界にはもっと多くの文字があります。

そのため、𝒳 (数学的な X)や 😄 (スマイル)のような特定の希少な文字は4バイトでエンコードされています。

これは比較のためのユニコード値です:

Character Unicode Bytes
a 0x0061 2
0x2248 2
𝒳 0x1d4b3 4
𝒴 0x1d4b4 4
😄 0x1f604 4

したがって、a と言った文字は 2バイトを占め、珍しいものは4バイトになります。

ユニコードは、4バイト文字がそれ全体でのみ意味を持つように作られています。

昔は JavaScript はそのことを知らなかったので、多くの文字列メソッドにはまだ問題があります。例えば、length はそれらを2つの文字であると考えます:

alert('😄'.length); // 2
alert('𝒳'.length); // 2

…ですが、1文字にしか見えませんよね? ポイントは length は4バイトを2つの2バイト文字として扱うということです。それらは併せてでしか考えられない(いわゆる “サロゲートペア”)ため、正しくありません。

通常、正規表現も2つの2バイト文字として “長い文字” を扱います。

これはおかしな結果に繋がります。例えば 𝒳 という文字列で [𝒳𝒴] を見つけようとしてみましょう。:

alert( '𝒳'.match(/[𝒳𝒴]/) ); // おかしな結果

デフォルトでは正規表現のエンジンはサロゲートペアを理解しないため、結果は間違っています。[𝒳𝒴] は2つではなく、4つの文字(𝒳 の左半分 (1), 𝒳 の右半分 (2), 𝒴 の左半分 (3), 𝒴 の右半分 (4)) と考えます。

なので、全体ではなく文字列 𝒳𝒳 の左半分を見つけます。

つまり、検索は '12'.match(/[1234]/) のように動作します – 1 が返ります(𝒳 の左半分)。

/.../u フラグはそれを直します。正規表現エンジンでサロゲートペアを利用可能にするので結果は正しくなります:

alert( '𝒳'.match(/[𝒳𝒴]/u) ); // 𝒳

フラグを忘れた場合、エラーが起きる場合があります:

'𝒳'.match(/[𝒳-𝒴]/); // SyntaxError: invalid range in character class

ここでは、正規表現 [𝒳-𝒴][12-34] と扱われます(2𝒳 の右部分、3𝒴 の左部分)。そしてその2つの半分 23 の間の範囲は認められません。

フラグを使うと正しく動作します:

alert( '𝒴'.match(/[𝒳-𝒵]/u) ); // 𝒴
チュートリアルマップ

コメント

コメントをする前に読んでください…
  • 自由に記事への追加や質問を投稿をしたり、それらに回答してください。
  • 数語のコードを挿入するには、<code> タグを使ってください。複数行の場合は <pre> を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。
  • 記事の中で理解できないことがあれば、詳しく説明してください。