コンテンツへスキップ
ものがたり
戻る

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ではこれらは同一の文字列になる、と明言してしまっているのよね。というかそもそもそこが疑問の出発点だったわけでして。


コメント

batta — 07/20/2007 11:48:53

むしろハゲシク逆で、0x20はNFKでこの2つを同一視させない
ように挿入されているようなものです。
たとえば 00DC が、0055 00A8 と一緒にされたら困るような
もの。そもそも半角カタカナで濁音を別文字扱いするという、
例外(縦書き考えると変でしょ?)を真面目に全角にも
適用しようとするからこういう罠にはまるのかな?

atsushieno — 07/20/2007 13:03:23

ええと、combining(U+3099)とnon-combining(U+309B)を混同していたのが↑のように書いた理由なので、U+309Bについては0x20がNFKC/NFKDで同一視を防ぐ意図で追加されていることは(現在では)分かります。

non-combiningであればすべからく同一視を防ぐべし、という設計意図(があるんですよね?)があることは、もっと後になって気付きました。

Footnotes

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


この記事を共有:

前の記事
次の記事
Unicode文字/文字列のつかいかた