正規化

Unicode 正規化形

[3] Unicode では、実際には同じ意味を表す列を複数の文字の列で表せることがあります。 この時、そのうちの一つの表現を代表として定めた上で、それへの変換方法を規定することができ、 その表現、あるいは変換方法を正規化形 (normalization form) といいます。 正規化形に変換することを正規化 (normalization) といいます。

仕様書

正規化形

[4] 正規化形にはいくつかのバリエーションがあります。

[5] 正規化形応用レベルの文脈上の制約を組み合わせた概念もあります。

[50] StringprepUnicode IDNA互換性処理PRECIS も広義の正規化と言えますが、 Unicode正規化に加えて大文字小文字の変換や禁止文字などその他の処理も組み合わさっています。 IDNA2008 による制約を満たす文字列も広義の正規化形と言えますが、やはり他の制約が組み合わさっています。

正規化形の性質

固有性

[24] 固有性 (uniqueness) Unicode 正規化形の最も重要な設計目標とされています。 2つの等価な文字列正規化形は完全に一致します >>6 7。すなわち、

安定性

[29] ここでいう安定性 (stability) 正規化に直接関係しない文字がそのまま無変更で残ることをいいます。具体的には、

効率性

[35] 正規化効率的 (efficiency) に実装可能であるとされています >>6 7。 具体的には、

  • [36] 正規化形が効率良く実装可能であって、とりわけ既に NFC または NFD である文字列に対して NFC を高速に得ることが可能です。 >>6 7
  • [37] 合成を行う正規化形は、必ずしも最初の形を生成するものではありません。 最小形の計算は高価である可能性があるためです。 >>6 7

安定性

[7] Unicode Consortium の規定する Unicode正規化形NFCNFDNFKCNFKD については、安定性、つまり Unicode の改訂を通じて正規化に非互換な変更が加わらないことがある程度保証されています。

[58] 基本的には、安定性文字が定義されている符号位置に関するものです。 新たな Unicodeの版で新しい文字が追加されると、その符号位置正規化の結果は変化するかもしれません。

強い正規化安定性

[10] 強い正規化安定性 (strong normalization stability) : Unicode 4.1 とそれ以降において、 ある版で割り当て済みの文字のみから構成される文字列正規化した結果は、 その文字列を以降の任意の版で正規化した結果と一致します。 >>9

[11] そのために、一旦割り当てられた文字分解写像正準結合クラスが改訂によって変化しないことが保証されています。 >>9

[12] この安定性は割り当て済みの文字のみで構成される場合についてのものであり、 未割当符号位置が含まれているときには必ずしも保証されません。

[38] この安定性が保証されるのは Unicode 4.1 以降ですが、実際には Unicode 3 以降においても Corrigendum #2, Corrigendum #3, Corrigendum #4, Corrigendum #5 の影響を受けない範囲では成立します。 >>6 11.2

弱い正規化安定性

[13] 弱い正規化安定性 (weak normalization stability) : Unicode 3.1 とそれ以降において、ある版で割り当て済みの文字のみから構成される文字列正規化した結果得られる文字列は、 以降の任意の版においても正規化済みです。また、それ以前で Unicode 3.1 までの版であって、 その文字列に含まれる文字すべてが含まれる版においてもまた、正規化済みです。 >>9>>6 11.1

[14] そのために、一旦割り当てられた文字分解写像がいくつかの例外ケースを除き改訂によって変化しないこと、 正準結合クラスが改訂によって変化しないことが保証されています。 >>9

[8] Unicode 正規化形合成版 (composition version) は「UCD 3.1.0」であると規定されています >>6 3。これは弱い正規化安定性が 3.1.0 以降について成立するということです。

[15] 強い正規化安定性が保証されれていれば、弱い正規化安定性もまた保証されます。

[18] 「XY」の2文字から「Z」の1文字への合成を追加する場合、 弱い正規化安定性が満たされるためには、 3文字すべてが新しい文字であるか、または XY のどちらかだけが古い文字であるかでなければなりません。 >>6 3

[20] また、正規化に影響するような既存の文字特性の変更も認められないことになります。 >>6 3

[16] 「Q + caron」という文字 (の列) を考えます。合成版である 3.1.0 にはこれを1符号位置で表す合成済文字は含まれていません。 基底文字結合文字の2文字で表すしかなく、これが正規形です。

[17] その後の版で、「Q + caron」を1文字で表す合成済文字が追加されたとしましょう。 自然に考えれば「Q-caron」 → 「Q」 + 「caron」という合成 (正準分解) を追加したいところですが、 そうすると以前の版で NFC だった「Q」 + 「caron」の2文字の表現が NFC ではなくなり、新しい「Q-caron」に正規化しなければならなくなってしまいます。 これは弱い正規化安定性の定義に反します。

[19] Unicode Consortium は新しい合成を追加することを非推奨としており、 従って「Q-caron」のような文字が後から追加されることは原則として無いようです。 >>6 3

Unicode 3.1 以前の非互換性

[22] Unicode 3.1.0 が「合成版」ということは、逆にそれまでの版と現在とでは互換性がない変更が行われていることを意味します。

[23] たとえば Unicode 2.1.9 においてハングル音節に関する互換性写像が削除され、 正規化の結果が変化しています。 >>6 6

[43] Unicode 3.0.1 と 3.1 の間に発行された訂正 #2 では、 誤って合成除外表から欠落していた1文字について、 合成除外表に追加され、非互換性が生じています。

Unicode 3.1 から Unicode 4.1 までの非互換性

[39] UAX #15 では、強い正規化安定性が保証されていない Unicode 4.1 よりも前の版との互換性が必要な時の対処方法として、

... の2通りを挙げて説明しています。

[42] >>41 は利用頻度が少ない文字だから問題ないことが多かろうなどと説明されていますが、 ひどいもんですなw

[44] Unicode 3.1 と 4.1 の間には訂正 #3訂正 #4が発行され、 6文字について正準分解が修正されています。

[45] Unicode 4.0.1 と 4.1 の間には訂正 #5 が発行され、「妨害」 の定義が修正されて正規化冪等性 (>>27) が保たれるようになっています。 それ以前も冪等性は設計目標に入っていましたが、定義の誤りにより厳密には成立していませんでした。

分解と合成

[55] Unicode では、符号化文字列文字列に対して正準分解正準合成互換分解といった演算が定義されています。 4つの正規化形は、その組み合わせとして次のように定義されています >>54

[67] 次のような手順群に整理できます >>54

  1. [64] 文字列完全分解を適用します。 NFC/NFD なら正準等価性を、NFKC/NFKD なら互換等価性を用います。
  2. [65] NFC/NFKC なら、
    1. [66] 文字列正準合成アルゴリズムを適用します。
  3. [68] それ以外なら、
    1. [63] 文字列正準再順序付けアルゴリズムを適用します。

大文字・小文字との関係

[52] >>51プログラミング言語識別子について大文字・小文字不区別正規化を両方採用する場合について考察しています。

応用

[61] Web では、一部で NFC が使われます。 XML完全正規化も使われます。 JavaScriptnormalize メソッドは、 NFCNFDNFKCNFKD に対応しています。

[62] それ以外の用法については、各正規化形の項を参照。

実装

[57] NFCNFDNFKCNFKDFCCFCD を実装しています。 対応する Unicodeの版は、Perl の版に依存します。

[60] XS 版と PP 版があります。

関連

[21] >>12>>18 のようにありますが、合成除外表の規定によれば新たな正準分解が追加されるとすると、 その展開先の文字に既存の文字が含まれているなら合成除外表に追加しなければならないこととなっており、 場合によっては未定義の符号位置が含まれていても新しい版で結果が変わらないことが保証される場合もあるようです。

メモ

[1] XProc: An XML Pipeline Language ( 版) <http://www.w3.org/TR/2010/REC-xproc-20100511/#p.serialization>

[2] XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition) ( ( 版)) <http://www.w3.org/TR/2010/REC-xpath-functions-20101214/#func-normalize-unicode>

[47] draft-duerst-i18n-norm - Character Normalization in IETF Protocols <http://tools.ietf.org/html/draft-duerst-i18n-norm>

[49] Character Model for the World Wide Web 1.0: Normalization ( ( 版)) <http://www.w3.org/TR/2012/WD-charmod-norm-20120501/>

[56] XPath and XQuery Functions and Operators 3.0 ( ( 版)) <http://www.w3.org/TR/xpath-functions-3/#func-normalize-unicode>

[69] XSLT 2.0 and XQuery 1.0 Serialization (Second Edition) ( ( 版)) <http://www.w3.org/TR/2010/REC-xslt-xquery-serialization-20101214/#unicode-normalization>

[70] XSLT 2.0 and XQuery 1.0 Serialization (Second Edition) ( ( 版)) <http://www.w3.org/TR/2010/REC-xslt-xquery-serialization-20101214/#XML_NORMALIZATION-FORM>

[71] XPath and XQuery Functions and Operators 3.1 () <https://www.w3.org/TR/2017/REC-xpath-functions-31-20170321/#func-normalize-unicode>

[72] XSLT and XQuery Serialization 3.1 () <https://www.w3.org/TR/2017/REC-xslt-xquery-serialization-31-20170321/#XML_NORMALIZATION-FORM>

[73] UTS #22: CharMapML () <http://www.unicode.org/reports/tr22/tr22-8.html#att_normalization>