■95545 / inTopicNo.6) |
Re[3]: サロゲートペアのDB40 |
□投稿者/ 魔界の仮面弁士 (2813回)-(2020/08/15(Sat) 12:52:42)
|
2020/08/15(Sat) 15:01:12 編集(投稿者)
■No95544 (S.Kos さん) に返信 > DB40を「二文字目」として数えているように思います。
異体字セレクタの話と、サロゲートペアの話がごっちゃになっているのだと思います。 書記素クラスターについて調べてみてください。
そもそも、何をもって「一文字」と見なすのかは、それぞれのシステム要件によって変化します。
タブ文字や改行、ゼロ幅スペースやLTR/RTL、結合文字や異体字セレクタ、 サロゲートペア、BOM の有無などがある場合、文字数をどのように数えるべきか、 あらかじめ考慮しておくことが望ましいでしょう。
> 「イと七」の「ほっけ」U+29E3D,29E3D_E0102は確かに「1文字」と数えますが、 > 「イとヒ」の「ほっけ」U+29E3D,29E3D_E0104はなんと「2文字」になってしまいます。
U+0000 〜 U+FFFF の範囲の文字は、16 bit で表されるので、1 つの ChrW で表現できます。 U+10000 〜 U+1FFFFF の範囲の文字は 16 bit に収まらず、2 つの ChrW で表現されます。これがサロゲートペア。
ホッケの場合、Unicode のコードポイントは U+29E3D です。
U+29E3D というのは、Unicode の第 0 面すなわち BMP(基本多言語面) に収まらないので、 サロゲートペアをもって表現されます。すなわち、 UTF-8 で表すと 4 バイト: F0,A9,B8,BD UTF-16LE で表すと 4 バイト: 67,D8, 3D,DE UTF-16BE で表すと 4 バイト: D8,67, DE,3D です。
変換ルールについては下記をご覧ください。 (サロゲートペアが必要なのは UTF-16 だけであり、UTF-8 や UTF-32 では使用されません) http://nomenclator.la.coocan.jp/unicode/ucs_utf.htm
つまり、VBA の String なら『ChrW(&HD867) & ChrW(&HDE3D)』、 あるいは『ChrB(&H67) & ChrB(&HD8) & ChrB(&H3D) & ChrB(&HDE)』で表されます。
このため、67,D8,3D,DE は、「本来は 1 文字」ではあるものの、 VBA の Len では 2 を返し、LenB では 4 を返す状態となります。
※VBA の文字列は、元々 UCS-2 をベースとしており、 32bit(2 バイト)で 1 文字となる前提で設計されています。
ここで、 No95541 でくまくまさんが提示してくださった > 上位代用符号位置 (D800-DBFF) > 下位代用符号位置 (DC00-DFFF) と比較してみましょう。
D867 が上位代用符号で、 DE3D が下位代用符号であることがわかりますね?
なので、上記から「実は U+10000 〜 U+1FFFFF の範囲の 1 文字である」と判断することができます。
さて、問題は異体字。
ホッケに対する異体字としては、 U+29E3D, U+E0100 … AJ1[CID+20315] U+29E3D, U+E0101 … AJ1[CID+15437] U+29E3D, U+E0102 … 文字情報[MJ055217], 汎用電子[JD9344] U+29E3D, U+E0103 … 文字情報[MJ055216], 汎用電子[KS523690], U+29E3D, U+E0104 … 文字情報[MJ055218] の 5 種類のシーケンスが存在します。 前半部の U+29E3D の扱いは、上記で説明したので省略。
でもって異体字セレクタ (VARIATION SELECTOR) は、 SVS で利用されるものが U+FE00 〜 U+FE0F (VS1〜VS16) で、 IVS で利用されるものが U+E0100 〜 U+E01EF (VS17〜VS256) です。 あとは、U+180B 〜 U+180D の MONGOLIAN FREE VARIATION SELECTOR (FS1〜FS3) ってのもあります。
SVS は BMP(基本多言語面) の 16bit 範囲に収まりますが、 IVS は BMP(基本多言語面) の 16bit 範囲に収まらないため、 ここでもまた、再度サロゲートペアをもって表現されます。
[MJ055217] の _E0102 部分なら、 UTF-8 で表すと 4 バイト: F3,A0,84,82 UTF-16LE で表すと 4 バイト: 40,DB, 02,DD UTF-16BE で表すと 4 バイト: DB,40, DD,02 です。
[MJ055218] の _E0104 部分なら、 UTF-8 で表すと 4 バイト: F3,A0,84,84 UTF-16LE で表すと 4 バイト: 40,DB, 82,DD UTF-16BE で表すと 4 バイト: DB,40, DD,04 です。
IVS を UTF-16 で表現した場合、 1 文字目が U+DB40 になっていますよね?
それが今回質問いただいた【DB40】が出現する理由です。
U+E0102 が、何故 U+DB40,U+DD02 に変化するのかは、先程の http://nomenclator.la.coocan.jp/unicode/ucs_utf.htm のルールに照らし合わせることで算出できますが、 くまくまさんが提示されている通り、IVS が > 上位代用符号位置 (DB40) > 下位代用符号位置 (DD00-DDEF) の範囲をとるのだと言い換えることもできます。
ホッケの異体字の場合、ベース文字がサロゲートペアで、 異体字セレクタもサロゲートペアという組み合わせになりますので、 VBA 上から見た場合、U+29E3D_E0102 も U+29E3D_E0104 も、 LenB では 8、Len では 4 という値を返すことになります。
不要であれば、異体字セレクタを 0 文字としてカウントするという手も ありますが、この手の問題は結合文字でも起こりえることに留意しましょう。
|
|