[3] Unicode では、実際には同じ意味を表す列を複数の文字の列で表せることがあります。 この時、そのうちの一つの表現を代表として定めた上で、それへの変換方法を規定することができ、 その表現、あるいは変換方法を正規化形といいます。 正規化形に変換することを正規化といいます。
[5] 正規化形と応用レベルの文脈上の制約を組み合わせた概念もあります。
[50] Stringprep やUnicode IDNA互換性処理や PRECIS も広義の正規化と言えますが、 Unicode の正規化に加えて大文字と小文字の変換や禁止文字などその他の処理も組み合わさっています。 IDNA2008 による制約を満たす文字列も広義の正規化形と言えますが、やはり他の制約が組み合わさっています。
[24] 固有性は Unicode 正規化形の最も重要な設計目標とされています。 2つの等価な文字列の正規化形は完全に一致します >>6 7。すなわち、
[7] Unicode Consortium の規定する Unicode の正規化形、NFC、NFD、 NFKC、NFKD については、安定性、つまり Unicode の改訂を通じて正規化に非互換な変更が加わらないことがある程度保証されています。
[58] 基本的には、安定性は文字が定義されている符号位置に関するものです。 新たな Unicodeの版で新しい文字が追加されると、その符号位置の正規化の結果は変化するかもしれません。
[10] 強い正規化安定性: 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] 弱い正規化安定性: Unicode 3.1 とそれ以降において、ある版で割り当て済みの文字のみから構成される文字列を正規化した結果得られる文字列は、 以降の任意の版においても正規化済みです。また、それ以前で Unicode 3.1 までの版であって、 その文字列に含まれる文字すべてが含まれる版においてもまた、正規化済みです。 >>9、>>6 11.1
[14] そのために、一旦割り当てられた文字の分解写像がいくつかの例外ケースを除き改訂によって変化しないこと、 正準結合クラスが改訂によって変化しないことが保証されています。 >>9
[15] 強い正規化安定性が保証されれていれば、弱い正規化安定性もまた保証されます。
[18] 「XY」の2文字から「Z」の1文字への合成を追加する場合、 弱い正規化安定性が満たされるためには、 3文字すべてが新しい文字であるか、または X と Y のどちらかだけが古い文字であるかでなければなりません。 >>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」に正規化しなければならなくなってしまいます。 これは弱い正規化安定性の定義に反します。
[22] Unicode 3.1.0 が「合成版」ということは、逆にそれまでの版と現在とでは互換性がない変更が行われていることを意味します。
[23] たとえば Unicode 2.1.9 においてハングル音節に関する互換性写像が削除され、 正規化の結果が変化しています。 >>6 6
[43] Unicode 3.0.1 と 3.1 の間に発行された訂正 #2 では、 誤って合成除外表から欠落していた1文字について、 合成除外表に追加され、非互換性が生じています。
[39] UAX #15 では、強い正規化安定性が保証されていない Unicode 4.1 よりも前の版との互換性が必要な時の対処方法として、
... の2通りを挙げて説明しています。
[44] Unicode 3.1 と 4.1 の間には訂正 #3と訂正 #4が発行され、 6文字について正準分解が修正されています。
[45] Unicode 4.0.1 と 4.1 の間には訂正 #5 が発行され、「妨害」 の定義が修正されて正規化の冪等性 (>>27) が保たれるようになっています。 それ以前も冪等性は設計目標に入っていましたが、定義の誤りにより厳密には成立していませんでした。
[55] Unicode では、符号化文字列文字列に対して正準分解、正準合成、互換分解といった演算が定義されています。 4つの正規化形は、その組み合わせとして次のように定義されています >>54。
[52] >>51 はプログラミング言語の識別子について大文字・小文字不区別と正規化を両方採用する場合について考察しています。
[77] NFKC, NFKD は破壊的です。 データの意味を致命的に変化させてしまうことが多いです。 特別に望ましい理由があって避けられない場合を除き、 使うべきではありません。
[80] NFC が好ましいとされており、 NFD はそれと逆方向の変換であるため、 特に理由がなければ NFD は使うべきではありません。
[96] NFC はデータを破壊することがあります。 影響が完全に理解されている場合を除き使うべきではありません。
[79] CJK統合漢字との字形差をCJK互換漢字で表したものが、 正規化で破壊されるケースがあります。 (ありますというか、符号点の個数でいえばそのほうが多い。)
[87]
その対策で導入された
CJK互換漢字に対応した SVS は、
CJK互換漢字と同じものを表しますが、
正規化で同一視される関係にはありません。
大元の CJK互換漢字はただの CJK統合漢字と同一視されてしまうという、
ねじれた関係にあります。
つまり正規化はデータの破壊には役に立ちますが、 検索の役には立ちません。
[94] 日本の常用漢字の旧字体のかなり多くがCJK互換漢字で表されています。 正規化すると旧字体から新字体への文字化けが起こります。
[95]
NFC, NFKC, NFKD をハングルに適用すると望ましからざる結果になることがあります。
[97] NFKC, NFKD はハングル以外でも文字の意味を考慮しないで似た文字に変化させてしまうものなので、 ハングルで適用前後で文意が変わってしまうとしても特別に問題ということでもなさそうです。 (文意が変わってしまうケースはハングル関係なく NFKC, NFKD を使うべきではないので。)
[98]
NFC は古ハングルが混じったデータに適用するとハングル音節の構造を壊してしまうことがあります。
[78]
combining enclosing mark
を使った合成済文字と結合文字列とで挙動が異なり、
正規化の対象から除外されているケースがあります。
[86]
正準等価な正規化により発生する結合文字の順序の入れ替えが好ましからざる変化をもたらすことがあります。
CGJ
[81]
単独のダイアクリティカルマークの多くは互換分解で
U+0020
+ 結合文字のダイアクリティカルマークに分解されてしまいます。
U+0020
になることによって都合が悪いケースもあります。
[82] ラテン文字やキリル文字の基底文字に重ねる形や一部を変形される形のダイアクリティカルマーク (overlaid diacritics) の扱いは一貫していません。 合成済文字と基底文字 + 結合文字の2種類の表現方法があっても、 大まかにいって、 数式と越南用のものは正規化され、 それ以外のラテン文字系のものは正規化されないようです。 >>164, >>88
[84]
合字は互換分解で分解されるとしても、
正準分解だけでは分解されません。
例えば
U+FB01
は 「fi」 に互換分解される
(正準分解されない) 合字です。
[83] つまり、 正規化に期待される効果、 例えば一致とか検索とか、 似た文字によるセキュリティー問題の回避のような類には、 Unicode で定められている正規化形では必ずしも十分ではありません。
[85] 合字に結合文字が付いていた場合、 互換分解によって結合文字の適用先が変化してしまいます。 >>164
[115] 正規化による結合文字の順序入れ替えや合成済文字と結合列の置換は意味的に等価ということになっていますが、 操作前後のレンダリングは実装によるところが大きく、 必ずしも同じように表示されるとは限りません。 >>114
[116] 規格上はどうだ、意味的にはこう定義されている、といったところで現実はそうなっていません。
[114] PDF 千夜一夜: PDFと文字 (41) – Unicode標準形式NFCの問題点(続き), , https://blog.antenna.co.jp/PDFTool/archives/2006/02/pdf_41.html
[91] 何も考えずに NFC や NFKC を使えばええやん、 と気づかずにデータを破壊する人々
[92] Normalization in HTML and CSS, , https://www.w3.org/International/questions/qa-html-css-normalization
[90] Unicode normalization could change the structure of a URL · Issue #626 · whatwg/url · GitHub, https://github.com/whatwg/url/issues/626
[93] 破壊的変換したら構造が破壊されるの、当たり前じゃんw
[101] >>99 字形の区別のために CJK互換漢字を使っている事例、 NFC だとハングル音節 + ハングル字母の2文字になるのをハングル字母3文字で表している事例。 これらで非 NFC が意図的に使われている。
[61] Web では、一部で NFC が使われます。 XML で完全正規化も使われます。
JavaScript の normalize
メソッドは、 NFC、NFD、
NFKC、NFKD に対応しています。
[119] PRECIS の正規化規則は4つの正規化形のいずれかを要求しています。
[102] プロトコルAとプロトコルBを組み合わせるとき、プロトコルAとプロトコルBで採用する Unicode正規化形が違うと困ったことになります。
[103] 指定が NFC と NFKC ならより厳しい NFKC にしておけばいいので問題ないです。 しかし指定が NFC と NFD なら、同時に従うことができません。 たまたま正規化によって変化しない文字だけで構成されるなら両方同時に適用された状態にもなりますが、 そんなシステムは実用に耐えません。
[104] こうした不都合が起こらないよう、 プロトコル (文書形式、データ構造等含め) は送信 (生成) において Unicode正規化を強制するべきではありません。
[105] これが現実にあまり問題視されないのは、
という理由と推測されます。
[108] あまり良く知らずにプロトコルの仕様書でおすすめされているからという理由で真面目に実装してしまうと、 罠にはまることになります。
[57] NFC、NFD、NFKC、NFKD、FCC、FCD を実装しています。 対応する Unicodeの版は、Perl の版に依存します。
[21] >>12 や >>18 のようにありますが、合成除外表の規定によれば新たな正準分解が追加されるとすると、 その展開先の文字に既存の文字が含まれているなら合成除外表に追加しなければならないこととなっており、 場合によっては未定義の符号位置が含まれていても新しい版で結果が変わらないことが保証される場合もあるようです。
[109] Unicode Normalization thread should slow down; summary needed, L. David Baron, , , https://lists.w3.org/Archives/Public/www-style/2009Feb/0231.html
[110] i18n の専門家を称する人々は各種 Web標準で Unicode正規化を要求するべきと主張していました (平成時代中期頃)。 しかし結局有効で有益で統一的な実装戦略を提出できませんでした。
[111] そのためいくつかの (当たり障りのない) 仕様に「できれば」程度の弱いおすすめとして潜り込ませることができたくらいで (またはまったく世の中に影響のない仕様の要件として提示できたくらいで)、 ほとんどの事業者はまったくスルーしました。
[112] そのおかげで有害無益な正規化で性能が激落ちするとか、 文字化けが多発するとか、 といった困った事案が Web標準が原因で発生することは避けられました。
[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
[74] Regexp.ja · neologd/mecab-ipadic-neologd Wiki () https://github.com/neologd/mecab-ipadic-neologd/wiki/Regexp.ja
[76] UAX #44: Unicode Character Database (, ) https://www.unicode.org/reports/tr44/#NormalizationTest_txt
[117] ENSIP-15: Normalization Standard - ENS Documentation, https://docs.ens.domains/ens-improvement-proposals/ensip-15-normalization-standard