ものがたり(旧)

atsushieno.hatenablog.com に続く

Unicode Normalizationはかな文字を正しく正規化するか?

激しく疑問である。

UAX#15によると、compatibility decompositionを適用した結果、全角濁点(0x309b)は、半角スペース(0x20)+半角濁点(0x3099)に置き換えられる。だから、たとえば「タ゛」(0x30bf 0x309b)は0x30bf 0x20 0x3099となる。

これって既に「ダ」(0x30c0)をcompatibility decomposeした結果(0x30bf 0x3099)と同一視できなかったりする。

さらに、全角濁点を使っていた方は、これをcompositionで元に戻そうとしても、0x20が邪魔で、「ダ」(0x30c0)に戻すことができない。0x20が除去されるルールは(少なくともUAX#15 revision 25には)存在しない(するわけがないと思う)。0x20はどうやらUnicode 1.xの頃から含まれていたようだ。

私見としては、0x20などをcompatibility mappingに含めているUnicodeData.txt sucksということなのだけど、どうでしょう。*1 とりあえずこんなところで仕様の問題でハマって時間くってもーた。

追記: ていうか別に同一でない文字列としてもいいんじゃん?と考えることもできそうだけど、UAX#15のA1.3 Normalization Forms KD and KC Examplesでは、NFKCではこれらは同一の文字列になる、と明言してしまっているのよね。というかそもそもそこが疑問の出発点だったわけでして。

*1:何を言ってるのか分からないYO!という人は、.NET 2.0にあるString.Normalize()で「ダ」と「タ゛」をNormalizationForm.FormKCで正規化して比較してみましょう。