BMP (基本多言語面)

Unicode の最初の 65,536 個のコードポイント (U+0000〜U+FFFF) を含む領域。日常的に使われるほとんどの文字がここに収録されており、この範囲外の文字はサロゲートペアで表現される。

BMP (Basic Multilingual Plane、基本多言語面) は、Unicode の 17 個の「面」(plane) のうち最初の面 (Plane 0) です。U+0000 から U+FFFF までの 65,536 個のコードポイントを含み、ASCII、ラテン文字、ギリシャ文字、キリル文字、アラビア文字、ひらがな、カタカナ、CJK 統合漢字の基本セット (約 20,000 字) など、世界の主要な文字体系のほとんどがここに収録されています。

BMP の外側には補助面 (Supplementary Planes) が 16 面あります。Plane 1 (SMP、補助多言語面) には絵文字、古代文字、音楽記号などが含まれます。Plane 2 (SIP、補助表意文字面) には CJK 統合漢字拡張 B 以降の漢字が収録されています。これらの補助面の文字は U+10000 以上のコードポイントを持ちます。

BMP と補助面の区別が文字数カウントに影響するのは、UTF-16 エンコーディングを使用する環境です。UTF-16 では BMP の文字は 2 バイト (1 コードユニット) で表現できますが、補助面の文字は 4 バイト (2 コードユニット = サロゲートペア) が必要です。JavaScript の String.length はコードユニット数を返すため、絵文字 (補助面) を含む文字列では見た目の文字数より大きな値が返ります。

具体例を見てみましょう。「A」(U+0041、BMP) は length が 1 です。「𠮷」(U+20BB7、CJK 統合漢字拡張 B) は BMP 外の文字で、length が 2 になります。「😀」(U+1F600、絵文字) も BMP 外で length は 2 です。さらに「👨‍👩‍👧‍👦」(家族の絵文字) は 7 つのコードポイント (うち 4 つが BMP 外) で構成され、length は 11 になります。

正確な文字数カウントには、BMP 内外を区別しない方法が必要です。JavaScript では Array.from(str).length[...str].length でコードポイント単位の文字数を取得できます。さらに正確を期すなら、Intl.Segmenter を使って書記素クラスタ単位でカウントすれば、結合文字や絵文字シーケンスも 1 文字として正しく数えられます。

BMP の中にも特殊な領域があります。U+D800〜U+DFFF はサロゲート用に予約されており、単独では有効な文字を表しません。U+E000〜U+F8FF は私用領域 (Private Use Area) で、フォントメーカーや企業が独自の文字を割り当てるために使います。U+FDD0〜U+FDEF と各面の末尾 2 コードポイントは「非文字」(noncharacter) として永久に文字に割り当てられません。

この記事を共有