World Wide Web のための文字モデル:文字列照合

W3C ワーキンググループノート

このバージョン:
https://www.w3.org/TR/2021/NOTE-charmod-norm-20210811/
最新公開バージョン:
https://www.w3.org/TR/charmod-norm/
最新編集者草案:
https://w3c.github.io/charmod-norm/
前のバージョン:
https://www.w3.org/TR/2019/NOTE-charmod-norm-20190204/
編集者:
Addison Phillips (Amazon.com)
参加:
GitHub w3c/charmod-norm
Issue を提出
コミット履歴
プルリクエスト

概要

この文書は、Character Model for the World Wide Web 1.0: Fundamentals [CHARMOD] を基礎として、仕様の作成者、 ソフトウェア開発者、およびコンテンツ開発者に、World Wide Web における文字列の同一性 照合に関する共通の参照情報を提供し、それによって相互運用性を高めるものです。

この文書の位置づけ

この節は、この文書の公開時点における位置づけを説明するものです。 他の文書がこの文書に取って代わる可能性があります。現在の W3C 公開文書の一覧と、この技術報告書の 最新リビジョンは、 W3C 技術報告書 インデックス( https://www.w3.org/TR/)で確認できます。

コメントの追跡を容易にするため、各コメントについて個別の issue またはメールを作成し、 URL を用いてコメント対象の節を示してください。

この文書は、Internationalization Working Group によって ワーキンググループノートとして公開されました。

この仕様についての議論には、 GitHub Issues が推奨されます。

ワーキンググループノートとしての公開は、 W3C 会員による支持を意味するものではありません。

これは草案文書であり、随時、他の文書によって更新、置換、 または廃止される可能性があります。この文書を進行中の作業以外のものとして引用することは 不適切です。

この文書は、 2017年8月1日版 W3C 特許 ポリシーの下で活動する グループによって作成されました。 このグループは、この文書が W3C 勧告になることを想定していません。

この文書は、 2020年9月15日版 W3C プロセス文書に従います。

1. 序論

1.1 目的と範囲

World Wide Web のための文字モデルの目的は、W3C のユニバーサルアクセスの目標に従い、 言語、用字、書記体系、または文化的慣習にかかわらず、すべての人々による Web の利用を容易にすることである。 この目標を達成するための基本的な前提条件の 1 つは、世界中で使用されている文字を、 十分に定義され、十分に理解された方法で伝送および処理できることである。

注記

この文書は、Character Model for the World Wide Web: Fundamentals [CHARMOD] を基礎としている。 この文書を正しく理解し適用するには、同文書の概念を理解していることが重要である。

World Wide Web のための文字モデルのこの部分では、文字列 照合、すなわち、仕様または実装が 2 つの文字列値が互いに同じであるか 異なるかを定義する処理を扱う。意味的に等価なテキストが 異なる方法で符号化され得ること、およびこれが(Web を構成する形式や プロトコルで使用されるような)形式言語にとって重要な照合操作に与える 影響について説明する。

この仕様の主な対象読者は、W3C 仕様の 開発者である。この仕様およびその一部は、他の W3C 仕様から参照することができ、 W3C 仕様、およびその他の仕様に対する適合基準を定義する。

この仕様のその他の対象読者には、ソフトウェア開発者、 コンテンツ開発者、および W3C 外部の仕様の作成者が含まれる。 ソフトウェア開発者およびコンテンツ開発者は、W3C 仕様を実装し利用する。この仕様は、W3C 仕様を実装し利用する実装(ソフトウェア)およびコンテンツに対する いくつかの適合基準を定義する。また、ソフトウェア開発者およびコンテンツ 開発者が、W3C 仕様における文字関連の規定を理解するのに役立つ。

この仕様で説明される文字モデルは、仕様の作成者、 ソフトウェア開発者、およびコンテンツ開発者に対して、 World Wide Web における一貫した相互運用可能なテキスト操作のための 共通の参照情報を提供する。これら 3 つのグループが協力することで、 世界中からアクセス可能な Web を構築できる。

1.2 この文書の構成

この文書は、文書形式における文字列 同一性照合のための規則と処理を定義することにより、この問題に関連する Web の基本的な構成要素の 1 つを定義する。これらの規則は、 各項目の一貫した処理を確保するため、文書形式で使用される 識別子および構造的マークアップ(構文的内容)を対象として設計されており、 仕様の作成者を対象としている。この 節は実装者を対象としている。

この文書は、2 つの主要な節に分かれている。

第 1 の節では、 文字列照合に関わる問題、Unicode とケース フォールディングがこれらの問題に与える影響、および これらの問題に対処するために使用され得るさまざまな課題と 正規化機構の概要を示す。

第 2 の節では、 形式言語で使用する文字列同一性照合の 要件と推奨事項を示す。これには、W3C 仕様で 定義される多くの文書形式などが含まれる。この節は主に、 Web を機能させ、文書作成者に一貫した結果を提供することに 関係している。

1.3 背景

この節では、この仕様で扱うトピックについて、 いくつかの歴史的背景を示す。

文字モデルの中核にあるのは、Unicode Standard [Unicode] と ISO/IEC 10646 [ISO10646] によって共同で定義される Universal Character Set (UCS) である。この文書では、Unicode を Universal Character Set の同義語として使用する。成功した 文字モデルにより、世界中の Web 利用者が、世界の書記 体系、用字、言語で(また異なるプラットフォーム上で)作成された Web 文書を交換し、読み、検索できるようになる。

Unicode Standard [Unicode] の最初の数章は、有用な背景資料である。

この仕様の重要な部分の開発に反映された要件については、 Requirements for String Identity Matching and String Indexing [CHARREQ] を参照のこと。

1.4 用語と表記法

この節には、この文書に固有の用語と表記法が含まれる。

Web はテキストベースの形式とプロトコルの上に構築されている。 文字列照合または検索を効果的に説明するためには、 要件や詳細が大きく異なるため、特定の形式またはプロトコル内にある さまざまな種類のテキストについて述べることができる用語を 確立する必要がある。

Unicode 符号位置(または「符号位置」)とは、 各 Unicode 文字に割り当てられた数値を指す。Unicode 符号位置は 0 から 0x10FFFF までの範囲である。(文字エンコーディング用語の より詳しい説明については、[CHARMOD] の 4.1 節を参照。)

Unicode 符号位置は U+hhhh と表記される。ここで hhhh は、少なくとも 4 桁、最大 6 桁の 16 進数字の列である。たとえば、文字 [U+20AC EURO SIGN] の符号位置は U+20AC であり、文字 😺 [U+1F63A SMILING CAT FACE WITH OPEN MOUTH] の符号位置は U+1F63A である。

この文書の例で使用される一部の文字は、特定のデバイスまたは 表示環境では意図どおりに表示されないことがある。通常、これは用字固有のフォントが ローカルにインストールされていないこと、または特定のレンダリングシステムの その他の制限によるものである。この文書では、多くの非ラテン文字について フォールバックグリフを提供するために Webfont を使用しているが、デバイスがそのフォントの表示を サポートしていない場合がある。可能な限り、編集者は例がそれでも理解可能であるよう 確保するよう努めている。

レガシー文字エンコーディングとは、 Unicode 文字集合の文字の全レパートリを符号化しない 文字エンコーディング形式である。

トランスコーダとは、 2 つの文字エンコーディング間でテキストを変換する処理である。 この文書では最も一般的に、 レガシー文字エンコーディング から UTF-8 などの Unicode エンコーディング 形式へ変換する処理を指す。

自然言語とは、人間が使用する音声、書記、または手話による コミュニケーションである(こちら [LTLI] も参照)

構文的内容とは、文書形式 またはプロトコルの構造に属する任意のテキストである。この定義には、 通常「マークアップ」と考えられる値が含まれるが、HTTP ヘッダー内のフィールド名など、 その他の値も含まれ得る。構文的内容は、形式またはプロトコルの 構造を形成するすべての文字からなる。たとえば、<>(およびそれらが囲む要素名やさまざまな属性)は、 HTML 文書における構文的内容の一部である。

構文的内容は通常、仕様または複数の仕様によって定義され、特定のプロトコルまたは形式に対して 定義済みで予約されたキーワードと、文書の「内容」ではなく文書の構造を 形成するために文書作成者によって定義される文字列トークンおよび識別子の 両方を含む。

語彙とは、形式またはプロトコルにおける、 予約キーワードの一覧、および/または(識別子などの) ユーザー提供値を割り当てるための規則である。 これには、異なる場所に現れることができる文字の範囲、順序、または種類に関する 制限を含めることができる。

たとえば、HTML はその要素名と属性名、および列挙属性 値を定義しており、これによって HTML の 構文的内容の 「語彙」が定義される。別の例として ECMAScript があり、識別子または変数名の先頭や本体に 現れることができる文字の範囲を制限する。文字列リテラルの値など、その他の場合には 異なる規則が適用される。

語彙内の値は、大きく 2 つの種類に分かれる。 すなわち、人間に見られ、読まれ、または操作されることを意図したもの (したがって自然言語テキストを含むことが期待され得るもの)と、 アプリケーションまたはプロトコルの内部的なものであり、人間とのやり取りを 意図しないものである。

ユーザー向け識別子とは、 語彙においてユーザーによって定義または割り当てられ、 少なくとも潜在的にエンドユーザーに見えることを意図した 識別子(したがって ローカライズ可能な内容)である。

アプリケーション内部識別子とは、 語彙においてユーザーによって定義または割り当てられるが、 文書形式またはプロトコルの内部にあり、人間とのやり取りを意図しない 識別子である。このような値は一般に ローカライズ可能な内容ではない。

ユーザー提供値とは、 構文的内容のうち、 語彙内で、 特定の形式またはプロトコルにおける予約キーワードとは異なり、ユーザーによって 割り当てられる未予約のものである。ユーザーは一般に、自分たちのユーザー提供値が、 好みの 自然言語の単語または句になり得ることを期待する。 これが、[CHARMOD] が 「仕様は U+0000 から U+10FFFF までを含む Unicode 符号位置の全範囲から 符号位置を任意に除外するべきではない(SHOULD NOT)」と推奨している理由である。

ローカライズ可能な 内容とは、人間が読むことを意図したテキストとしての文書内容を指し、 文書構造の一部を形成する周囲または埋め込みの構文的内容は 指さない。ただし、構文的内容にはローカライズ可能な内容が埋め込まれることがある。 たとえば、[HTML] の img 要素が、画像の説明を含む alt 属性を持つ場合である。

この文書の文脈における リソースとは、特定の文書、ファイル、または プロトコル「メッセージ」であり、ローカライズ可能な内容と、それを取り囲む、 または含む識別子などの 構文的内容の両方を含む。たとえば、一部の CSS と、 JavaScript が埋め込まれた数個の script タグも含む HTML 文書では、その HTML 文書全体を ファイルとして考えたものがリソースである。この用語は、[RFC3986] で使用される 「resource」という用語に意図的に類似させているが、ここではこの用語を緩やかに適用している。

書記素とは、あるテキストの視覚的表現において、 典型的な利用者が 1 つの単位(文字)として知覚する 1 つ以上の文字の列である。書記素は、ソートやテキスト選択などの 多くのテキスト操作にとって重要であるため、利用者が知覚する各文字の間の境界を 計算できる必要がある。Unicode は、 Unicode Standard Annex #29: Text Segmentation [UAX29] で 書記素を計算する既定の機構を定義し、この近似を 書記素クラスタと呼んでいる。既定の書記素クラスタには 2 種類が定義されている。特に明記しない限り、この文書における書記素 クラスタは、拡張既定書記素クラスタを指す。(書記素クラスタの説明は、 Unicode Standard の 2 節 [Unicode] にもある。Unicode Standard バージョン 8.0 の 2.11 節 の終わり近くも参照。)

自然言語ごとに異なる必要があるため、書記素クラスタにも調整が必要になることがある。 たとえば、スロバキア語の利用者は、既定では 2 つの書記素クラスタである "ch" の組を、1 つの書記素クラスタとして扱いたい場合がある。 文字列内容の言語とエンドユーザーの設定との相互作用は複雑になり得ることに注意。

1.4.1 用語の例

この節では、上で定義した用語の一部を示す。説明のため、次の小さな HTML ファイルを例として使用する (参照用に行番号を追加している)。

1 <html lang="en" dir="ltr">

2 <head>

3   <meta charset="UTF-8">

4   <title>Shakespeare</title>

5 </head>

6 <body>

7   <img src="shakespeare.jpg" alt="William Shakespeare" id="shakespeare_image">

8   <p>What&#x2019;s in a name? That which we call a rose by any other name would smell as sweet.</p>

9 </body>

10 </html>

  • 黒い長方形の内側にあるすべて(すなわち、この HTML ファイル内のもの)は、 リソースの一部である。
  • この場合の 構文的内容には、すべての HTML マークアップが含まれる。構文的内容の一部ではない文字列は 2 つだけである。4 行目の語 "Shakespeare" と、8 行目の文 "What’s in a name? That which we call a rose by any other name would smell as sweet." である。(8 行目の文に 埋め込まれた HTML エンティティ &#x2019; は、構文的内容の一部 である。)
  • ローカライズ可能な内容は、 灰色の背景に太字の青いフォントで示されている。非構文的内容に加えて、 7 行目の alt 値(William Shakespeare)も ローカライズ可能な内容である。
  • ユーザー提供値は 斜体で示されている。この場合、 7 行目には 3 つのユーザー提供値がある。すなわち、img タグの srcalt、および id 属性の値である。さらに、1 行目の lang 属性の値と、3 行目の charset 属性の値も ユーザー提供値である。
  • 語彙は、赤い 下線で示されている。HTML 文書の語彙とは、[HTML] で定義された要素と属性 (および、上の例における dir 属性の値 ltr など、 一部の属性値)である。
注記

上記のすべてのテキスト(テキストファイル内のすべてのテキスト)がリソースを構成する。 あるリソースが ローカライズ可能な内容をまったく 含まないこともあり得る(オレンジ色の長方形としてスタイル指定された 4 つの空の div 要素からなる HTML 文書を考えよ)。また、リソースが 構文的内容をまったく含まずローカライズ可能な内容だけで構成されることもあり得る。 たとえば、Hamlet からの独白を含むプレーンテキストファイルである。 さらに、HTML エンティティ &#x2019; がローカライズ可能な内容内に現れ、 このリソースにおいてローカライズ可能な内容と構文的内容の両方に属することにも注意。

1.5 適合性

この仕様では、非規範的と記された節に加えて、すべての作成ガイドライン、図、 例、および注記は非規範的である。この仕様のその他すべては規範的である。

この文書におけるキーワード MAYMUSTMUST NOTOPTIONALRECOMMENDEDSHOULD、および SHOULD NOT は、 ここに示すようにすべて大文字で現れる場合に限り、 BCP 14 [RFC2119] [RFC8174] に記述されているように解釈される。

この文書は、他の仕様の作成者のためのベストプラクティス、および 実装とコンテンツ作成者のための推奨事項を説明する。これらのベストプラクティスは、 Internationalization Working Group の文書 Internationalization Best Practices for Spec Developers [INTERNATIONAL-SPECS] にも記載されており、 これは W3C 仕様におけるすべての国際化ベストプラクティスの 一般的な参照情報として機能することを意図している。

この文書のベストプラクティスでは、特定の推奨事項に関する Internationalization Working Group の意図を明確にするため、 [RFC2119] キーワードを使用する。 この文書の推奨事項に従うことは、W3C の「広範なレビュー」過程、実装時、または 作成者が作成するコンテンツにおける問題を回避するのに役立つ。この文書自体は規範的ではなく、 随時改訂され得る。

仕様は、次の場合にこの文書への適合を主張できる。

  1. 命令語が MUST または MUST NOT である [S] が前置された適合基準に違反しないこと
  2. 命令語が SHOULDSHOULD NOT、または RECOMMENDED である基準から逸脱する場合、その理由を文書化すること
  3. 実装がこの文書に適合することを適合要件とすること
  4. コンテンツがこの文書に適合することを適合要件とすること
注記

仕様に課される要件は、それらの仕様への適合を主張する 実装またはコンテンツに対して、間接的に要件が課される原因となる場合がある。

この仕様が手続き的な記述を含む場合、それは望ましい外部から観察可能な振る舞いを 指定する方法として理解されるべきである。実装は、観察可能な振る舞いに影響を与えない限り、 同じ結果を達成するために他の手段を使用してもよい(MAY)。

2. 文字列照合の問題

Web は主に、文字データに基づく文書形式とプロトコルで構成されている。 これらの形式またはプロトコルは、何らかの構造的マークアップまたは 構文的内容を含む テキストファイルを主とするリソースの集合と見なすことができる。 このような構文的内容または文書データを処理するには、 照合(正規表現を含む)、インデックス付け、検索、ソートなどの 文字列ベースの操作が必要である。

利用者、特に実装者は、類似した文字列が一致するか一致しないか、または テキスト、特に構文的内容に対して適用し得るさまざまな変換の有効性について、 しばしば素朴な期待を抱くことがあるが、これは Web 上の多くの種類の テキスト処理にも当てはまる。

根本的に Web は、テキストが文書内で表現され得るさまざまな方法に敏感であるため、 同じテキストを表現できる異なる方法を考慮しないと、利用者を混乱させたり、 予期しない、または不満の残る結果を引き起こしたりする可能性がある。以下の節では、 この文書は、Web 上のテキストに対する利用者の認識と、Web が依存する文字列処理の 両方に影響する、テキストのさまざまな種類の変異について検討する。

2.1 ケースマッピングとケースフォールディング

一部の用字および書記体系では、大文字、小文字、タイトルケース文字を区別する。インドの ブラーフミー系文字、アラビア文字、中国語・日本語・韓国語の表記に用いられる文字を含む 多くの用字には大文字小文字の区別はないが、いくつかの重要な用字には存在する。その例として、 この文書の大部分で用いられているラテン文字のほか、ギリシャ文字、アルメニア文字、 キリル文字などがある。

ケースマッピングとは、 文字を大文字、小文字、タイトルケースなど、特定のケースに変換する処理である。 大文字小文字の区別を持つ用字について、Unicode は各 Unicode 符号位置に対して 既定の大文字、小文字、タイトルケース文字マッピングを定義している。 ケースマッピングは最初は単純に見える。しかし、多様な言語における Unicode の全範囲を 扱う場合には、考慮すべき変異が存在する。

注記

ケースフォールディングとは、 大文字小文字だけが異なる 2 つのテキストを、比較の目的で同一にする処理であり、 すなわち文字列照合のためのものである。これは、主に表示目的のために意図される ケースマッピングとは異なる。 既定のケースマッピングと同様に、Unicode は各 Unicode 符号位置に対して既定の ケースフォールドマッピング(「ケースフォールディング」)を定義している。Unicode は 2 つの形式のケースフォールディングを定義しており、以下でそれらを検討する。

大部分の用字には大文字小文字の区別がないため、ケースマッピングと同様に、ほとんどの Unicode 符号位置にはケースフォールディングは不要である。ケースフォールディングを持つ 符号位置については、その大多数が、対応する別の単一の(通常は小文字の)符号位置への 単純で直接的なマッピングを持つ。Unicode はこのフォールディングの集合を common と呼ぶ。これは、Unicode が定義する 2 種類の ケースフォールディングの両方にこれらが含まれるためである。

少数の文字には、1 つの Unicode 符号位置を 2 つ以上の符号位置にマップする ケースフォールディングがある。このケースフォールディングの集合は full ケースフォールディングと呼ばれる。 fullcommon のケースフォールディングは、 Unicode 全体に対する既定のケースフォールディングを提供するために併用される。 この文書では、この形式のケースフォールディングを 完全 ケースフォールディングまたは Unicode full と呼ぶ。

一部のアプリケーションはケースフォールド操作を行う際に追加の記憶領域を割り当てられないため、 Unicode は、通常であればより多い、またはより少ない符号位置にフォールドされる符号位置を、 比較目的で代わりに 1 つの符号位置にマップする simple ケースフォールディングを提供している。 完全フォールディングとは異なり、このフォールディングは必ず内容(場合によっては テキストの意味)を変更する。完全ケースフォールディングと同様に、 単純ケースフォールディングまたは Unicode simple ケースフォールドは、Unicode の全範囲をカバーするために simplecommon のマッピングを組み合わせたものである。 Unicode simple は Web での使用には 適切ではない。

ケースフォールディングは、後で復元できない情報を文字列から取り除くことに注意。 たとえば、ドイツ語における 2 つの s 文字は、 フォールドされていないテキストにおいて必ずしも ß を表すとは限らない。

2.1.1 言語依存性

ケースマッピングとケースフォールディングのもう 1 つの側面は、それらが言語に依存し得ることである。 Unicode は各符号化文字に対して既定のケースマッピングと ケースフォールディングを定義しているが、これらは既定値にすぎず、すべての場合に 適切であるとは限らない。一部の言語では、特定の言語上の必要性を満たすために、 ケースマッピングを調整する必要がある。その例の 1 つが、ラテン文字で書かれる テュルク諸語である。

上の例(およびこの文書全般)は、照合の目的でのケースフォールディングに焦点を当てているが、 ケースマッピングも言語固有であることに注意。トルコで 2 番目に大きい都市の名前は "Diyarbakır" であり、点付きと点なしの両方の文字 i を含んでいる。

2.1.2 ケースフォールディングの用途

一部の文書形式またはプロトコルは、自らが定義する 語彙や、 その形式またはプロトコルによって許可される ユーザー提供値において、 大文字小文字の変異を無視することで、相互運用性を支援したり、コンテンツ作成者を助けたりしようとする。

場合によっては、大文字小文字が意味的に重要でない方法で変化することがある。 または、その変化が利用者の完全な制御下にない場合もある。これは文書を検索する場合に 特に当てはまるが、識別子など、利用者またはコンテンツが生成した値を照合する規則を 定義する場合にも当てはまることがある。このような状況では、代わりに 大文字小文字を区別しない照合が望ましい場合がある。

語彙を定義する際の重要な考慮事項の 1 つは、その値が Unicode の ASCII [ASCII] サブセットに制限されているか、または語彙が、ラテン文字のアクセント付き文字や、 非ラテン文字を含む広範囲の Unicode など、より複雑なケースフォールディング要件を 潜在的に持つ文字の使用を許可しているかである。これらの異なる要件に対処するため、 この文書では、文書形式またはプロトコルにおける文字列同一性照合の目的で、 4 種類のケースフォールド照合を定義する。

大文字小文字を区別する照合: 符号位置はケースフォールディングなしで直接比較される。

ASCII の大文字小文字を区別しない照合は、[INFRA] で 定義されている。 この定義は、0x41 から 0x5A(A から Z)の範囲にあるすべての ASCII 符号位置が、 0x61 から 0x7A(a から z)の範囲にある対応する符号位置にマップされたかのように、 2 つの符号位置列を比較する。語彙自体が ASCII に制限されている場合、 ASCII の大文字小文字を区別しない照合が必要になることがある。

Unicode の大文字小文字を区別しない照合は、 Unicode full ケースフォールディング(上記参照)が 両方の入力列に適用されたかのように、2 つの符号位置列を比較する。

言語依存の大文字小文字を区別する照合は、 文書形式またはプロトコルが構文的内容の言語に関する情報を含み、言語依存の ケースフォールディングを適切に適用できるような、まれな場合に有用である。 これらのケースフォールディングは、Unicode Consortium の Common Locale Data Repository [UAX35] プロジェクトで定義されている。

ケースフォールディングの扱い方に関する助言については、§ 3.2.6 ケースフォールディングに関する追加の考慮事項を参照。

2.2 Unicode 正規化

Unicode テキストでは、別の種類の変異が生じることがある。すなわち、同じ抽象文字を表すために、 複数の異なる Unicode 符号位置列を使用できる場合がある。 符号位置を比較してテキストを検索または照合する場合、こうした符号化の変異により、 利用者が同じであると期待するテキスト値が一致しなくなる。

アプリケーションは、異なる符号位置列を用いるテキストにおいて 意味的等価性を見つける必要があるため、Unicode は、 意味的に等価な 2 つのテキストを同一にする手段、すなわち Unicode 正規化形式 [UAX15] を定義している。

リソースは、こうした変異の影響を受けやすいことが多い。 これは、Web 上の仕様や実装が、テキストの Unicode 正規化を要求しておらず、また後で 構文的内容ユーザー提供値を含む)および ローカライズ可能な内容を処理する際に使用される文字列照合アルゴリズムを 考慮していないためである。このため、コンテンツ開発者は、後で問題が発生しないよう、 一貫した表現を提供していることを確保する必要がある。

しかし、特定の リソース またはリソース集合が一貫したテキスト表現を使用していることを、利用者が保証するのは 難しい場合がある。なぜなら、その違いは通常、テキストとして表示したときには見えないからである。 したがって、ツールや実装は、視覚的または論理的に等価であり、利用者の考えでは 一致する「はず」の文字列が、異なる値と見なされる場合に利用者が経験する困難を 考慮する必要がある。利用者がこれらの違いを確認したり、適切に正規化したりできる 手段を提供することで、エンドユーザーはソース文書内の見えない違いから生じる失敗を 回避できるようになる。たとえば、W3C Validator は、 HTML 文書が完全に Unicode 正規化形式 C になっていない場合に警告する。

2.2.1 正準等価性と 互換等価性

Unicode は文字間の等価性として、正準等価性互換等価性の 2 種類を定義している。

正準 等価性とは、同じ抽象文字を表す Unicode 符号位置または Unicode 符号位置列の間にある基本的な等価性である。正準等価な列は、 理想的には同じ視覚的外観を持つべきであり(ただし、多少異なって見える原因となる要因は多い)、 同一であるかのように扱い、処理されるべきである。Unicode は、 異なる方法で符号化されているが正準等価な 2 つのテキスト間の主要な 区別を取り除く、正準分解と呼ばれる処理を定義している。

Unicode によって定義される正準等価性の例には、次のものが含まれる。

  • Ç vs. 合成済み文字と結合列。 一部の文字は、基底 文字に 1 つ以上の結合文字を続けることで構成できる。同じ 文字が、個別の「合成済み」文字として符号化されることもある。 この例では、文字 Ç [U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA] は、 基底文字 C [U+0043 LATIN CAPITAL LETTER C] で始まり、その後に ◌̧ [U+0327 COMBINING CEDILLA​] が続く文字列と 正準等価である。このような等価性は、複数の結合記号を持つ文字にも及び得る。
  • q̣̇ vs.q̣̇ 結合記号の順序。 基底文字が 複数の結合記号によって修飾される場合、結合記号の順序が異なる 文字を表さないことがある。ここでは、列 q [U+0071 LATIN SMALL LETTER Q]  ̇ [U+0307 COMBINING DOT ABOVE​]  ̣ [U+0323 COMBINING DOT BELOW​]q [U+0071 LATIN SMALL LETTER Q]  ̣ [U+0323 COMBINING DOT BELOW​]  ̇ [U+0307 COMBINING DOT ABOVE​] は、結合記号の順序が異なっていても等価である。 この例は慎重に選ばれていることに注意。上付き点文字と下付き点文字は、 基底文字の反対側にある。同じ側にある結合発音区別記号の順序は、 しばしば位置上の意味を持つ(ただし、表示において順序が問題にならない場合もある)。
  • vs.Ω 単一対応マッピング。 これらは、レガシー文字エンコーディングを サポートするために、他の点では等価な文字を個別に符号化する必要から生じる。 この例では、オーム記号 [U+2126 OHM SYMBOL] は、ギリシャ文字オメガ Ω [U+03A9 GREEK CAPITAL LETTER OMEGA] と正準等価であり(かつ外観も同一である)。 (単一対応の別の例は、上の 符号化の変異の例にある [U+212B ANGSTROM SIGN] である)
  • vs.가 ハングル。 ハングル文字は、 韓国語を書くために使用される。この文字は論理的に構成されており、 各音節は、子音と母音を表す特定の下位部分から形成される、 ほぼ正方形の 書記素である。 これらの特定の下位部分は jamo と呼ばれ、Unicode で符号化されている。 合成済み音節も同様に符号化されている。したがって、音節 [U+AC00 [Hangul Syllable, First]] は、その構成要素である jamo 文字 가 [U+1100 HANGUL CHOSEONG KIYEOK + U+1161 HANGUL JUNGSEONG A] と正準等価である。

互換等価性とは、同じ抽象文字を表す Unicode 文字または Unicode 文字列の間の、より弱い等価性であるが、 視覚的外観または振る舞いが異なる場合がある。一般に、 互換分解と呼ばれる処理は、上付き、下付き、回転、 丸囲みなどの書式上の変異を取り除くが、他の変異も生じる。 多くの場合、互換分解を持つ文字は意味上の区別を表しているため、 異なる文字の使用をその互換分解で置き換えると、テキストの意味が変わる可能性がある。 互換分解後に等価となるテキストは、多くの場合、その前には同一であるとは 認識されておらず、形式言語では等価として扱うべきではない (SHOULD NOT)。

上の表で重要なのは、示されている文字が、文脈やスタイルによる単なる表示上の 変異ではなく、実際の Unicode 符号位置であるという点である。 各文字は、さまざまなレガシー文字エンコーディングとの互換性のために Unicode に符号化されたものである。これらは、それぞれの非互換対応文字に対して 通常使用される表示処理の通常の種類と混同すべきではない。

たとえば、アラビア文字のテキストの大部分は、Unicode のアラビア文字ブロック (U+0600 から始まる)の文字を使用する。 テキストの表示に使用される実際のグリフは、単語内の位置 (語頭、語中、語末、または独立)に基づき、フォントとテキスト処理ロジックを用いて 選択される。この処理は「字形形成」と呼ばれる。上の表では、アラビア文字 ه [U+0647 ARABIC LETTER HEH] の 4 つの表示形が示されている。 示されている文字は U+FE00 ブロック内の 互換文字であり、それぞれ特定の「位置」字形を表し、示された 4 つの符号位置はそれぞれ 通常のアラビア文字 ه [U+0647 ARABIC LETTER HEH] への互換分解を持つ。これらの表示形は、同等の表示形を含む レガシー文字エンコーディングとの 往復符号化変換をサポートするためだけに意図されている。それ以外の場合、文字 'heh' の列を含む文字列は、単に一連の U+0647 符号位置として 符号化され、レンダリングシステムとフォントが適切な字形を提供する。

同様に、半角形と全角形、および(縦書きで使用するための)回転文字の変異は、 主にレガシー文字エンコーディングとの互換性のために、別個の符号位置として 符号化されている。多くの場合、これらの変異は East Asian Width [UAX11] で 説明される Unicode プロパティに関連付けられている。 縦書きの表示形式についての議論は、Unicode Vertical Text Layout [UTR50] も参照のこと。

上記のような互換分解を持つ文字の場合、K Unicode 正規化形式は、テキストを「通常の」または「期待される」 Unicode 符号位置に変換する。しかし、こうした互換文字の存在をもって、 通常のテキストレイアウトおよび表示の過程で生成される類似した外観の 変異が Unicode 正規化の影響を受けるとみなすことはできない。 それらは影響を受けない。

2.2.2 合成と 分解

Unicode によって定義されるこれら 2 種類の等価性は、さらに 「分解」と「合成」という別の対の変異によって分類される。 「分解」では、視覚的文字の分離可能な論理部分が、基底文字と 結合記号の列に分解され、その結果の符号位置が固定された正準順序に置かれる。 「合成」では、分解が実行された後、一定の規則に従って、結合記号が その基底文字と再結合される。

警告

大まかに言えば、NFC は、各 結合文字列(基底文字に 1 つ以上の結合文字が続くもの)が、可能な限り、 正準等価な合成済み文字で置き換えられるように定義されている。

これが何を意味しないかに注意することは、かなり重要である。 得られる文字列には、なお結合記号が含まれ得る。なぜなら、すべての文字列に 合成済みの等価物があるわけではないからである。実際、これまで見てきたように、 多くの用字では、この例におけるデーヴァナーガリーの 母音のように、結合記号の使用に代わるものが存在しない。他の場合には、 特定の基底文字と結合記号が、合成済み文字で置き換えられないことがある。 これは、その組み合わせが正規化規則によってブロックされるためである。 たとえば、一部のインド系文字では、対応する合成済み文字が存在するにもかかわらず、 合成除外規則のために、基底文字と発音区別記号の特定の列を合成しない。 合成は、結合されるはずの 2 つの文字の間に別の結合記号があることによっても ブロックされ得る。

2.2.3 Unicode 正規化形式

Unicode 正規化形式は 4 つある。それぞれの形式は、文字コードを用いて命名される。

  • D(または NFD)は、正準分解を表す。
  • C(または NFC)は 合成を表し、正準分解に続いて合成を行うものである。
  • KD(または NFKD)は、互換分解を表す (文字 C はすでに使用されているため K を用いる)。
  • KC(または NFKC)は、互換分解に続いて合成を行うことを表す。

Unicode 正規化は、これら(および同じ文字を表すその他の潜在的なエスケープ列)を、 わずか 3 つの可能な変異にまで減らす。しかし、Unicode 正規化はすべての テキスト上の区別を取り除くわけではなく、Unicode 正規化の適用が、特定の文脈で 区別的または意味のある意味を取り除いてしまうこともある。たとえば、次のとおりである。

  • すべての互換文字が互換分解を持つわけではない。
  • 見た目が似ている、または類似した意味を持つ一部の文字は、Unicode では実際には 異なる文字であり、それらを結び付ける正準分解または互換分解を持たない。 たとえば、 [U+3002 IDEOGRAPHIC FULL STOP] は、中国語や日本語などの言語で文末の 句点として使用される。しかし、これは ASCII の ピリオド文字 . [U+002E FULL STOP] と等価とは 見なされない。
  • 一部の文字変異は、Unicode 正規化形式では扱われない。たとえば、 大文字、タイトルケース、小文字の変異は、テキストを比較する際に別途扱わなければならない、 独立したテキスト上の変異である。
  • 互換正規化は意味を取り除く。たとえば、文字列 (文字 ½ [U+00BD VULGAR FRACTION ONE HALF] を含む)は、 互換正規化形式のいずれか (すなわち NFKD または NFKC)で正規化されると、 ASCII 文字列 81/2 になる。

2.3 同一に見える文字と正規化の限界

多くの利用者は、同一に見える 2 つの文字列—特定の Unicode 正規化形式が 適用されたものを含む—が、実際には同じ基礎となる Unicode 符号位置を 使用していない場合があることを知って驚く。これには、より破壊的な NFKC および NFKD 互換正規化形式が 適用された文字列も含まれる。文字列、トークン、または識別子が視覚的に同じに見える場合でも、 それらは異なる方法で符号化されていることがある。

Unicode の正準正規化形式は、特定の抽象文字または書記素クラスタに使用できる 複数の異なる符号位置列を、同じ符号位置列を使用するように畳み込むことに関係している。 しかし、論理的に異なる文字または書記素クラスタが、なお同じ、または非常に 似て見えることがある。1 組の 書記素が同一(または非常に類似)に見える場合、 それらは 同形異字と呼ばれる。1 組の書記素が類似して見える、または 同形異字であるが、実際には論理的に異なる文字または 文字列を表す場合、それらは 紛らわしいとされる。

同一または同一に見える外観の例は、単一の用字内でも現れることがある。これは "0" と "O"、または "l" と "1" のような、形状の似た文字という形をとり得る。 しかし、他の用字や異なる互換文字の使用は、はるかに区別しにくい変異を 示すことがある。場合によっては Unicode 正規化がこれらをまとめるが、多くの場合はそうしない。

外観が同一または紛らわしい文字は、なりすましや その他のセキュリティリスクをもたらす可能性がある。これは、単一の用字内でも、 別々の用字にある類似文字についても当てはまる。同形グリフと紛らわしさについての さらなる議論と例として、有用な参考文献の 1 つは [UTS39] である。

同一または類似して見える文字に加えて、反対の問題も存在する。 Unicode 正規化は、NFKC および NFKD 互換形式であっても、 同じ内在的な意味または機能を持つが、外観または使用法が異なる文字を まとめることはない。たとえば、U+002E (.) と U+3002 (。) はどちらも文末の句読点として機能するが、 文字が異なる同一性を持つため、その区別は正規化によって取り除かれない。

2.4 正規化と ケースフォールディングの相互作用

大文字小文字を区別しない方法で文字列を照合する場合、複雑な点の 1 つは、 元の文字列が正規化されていたとしても、ケースフォールディング処理によって 正規化されていない文字列が生成され得ることである。文字列比較は符号位置列の一致に 依存するため、照合処理を信頼できるものにするには、ケースフォールドされた各文字列を 正規化しなければならない。

Unicode の正準正規化形式(NFC または NFD)と ケースフォールディングを併用する場合、それらは閉じている。すなわち、いったん文字列が ケースフォールドされ、その後に NFD または NFC が適用されると、同じケースフォールディング または Unicode 正規化形式をさらに適用しても、異なる文字列にはならない。

文字間の 互換等価性 (言い換えると、NFKC/NFKD 形式)について文字列を比較する場合、 ケースフォールドして正規化する操作は 2 回実行しなければならない。これは、 互換分解ステップによりケースフォールドが必要な文字が生じる可能性があり、 その後のケースフォールドにより、さらに正規化しなければならない列が生じる可能性があるためである。

2.4.1 なぜ 正規化はケースフォールディングに先行するのか?

Unicode における 正準ケースフォールド照合(規則 [D145])および 互換ケースフォールド照合(規則 [D146])の定義には、 複数の正規化ステップが含まれる。これにより、大文字小文字を区別しない照合を実行する 複雑さとコストが増す。ケースフォールディングを実行する前の最初の ケースフォールドステップは、この節で詳述する特定の隅の事例に対処するものである。

Unicode のケースフォールド照合処理における最後の正規化ステップは、 結果の文字列が特定の Unicode 正規化形式になることを確保するために存在する。 結果として得られるケースフォールド済み文字列を保存したり利用者に表示したりする場合は、 ケースフォールド操作によって生成された非正規化列を、表示のために再正規化することが 良い慣行である。しかし、追加の正規化を実行しても文字列比較の結果は変わらないため、 このステップは Unicode 正準 ケースフォールド正規化ステップおよび Unicode 互換ケースフォールド正規化ステップでは OPTIONAL である。

63 個のギリシャ語の合成済み文字には、文字    ͅ [U+0345 COMBINING GREEK YPOGEGRAMMENI] を含む分解マッピング(すなわち NFD 形式へ正規化されるもの)がある。これは、 下付きイオタを表す発音区別記号(prosgegrammei または ypogegrammeni と呼ばれる)である。この記号は、古代または古典ギリシャ語に 見られる正書法上の形式を表し、より現代的な形の言語には存在しない音を表す。 これらの文字の大文字およびタイトルケースマッピングは、この結合記号を独立した基底文字 iota として分離する。タイトル/大文字マッピングとの一貫性のため、 これらの文字のケースフォールドマッピングにはしたがって ι [U+03B9 GREEK SMALL LETTER IOTA] が含まれる (Unicode のケースフォールドは一般に小文字へのものであることを 思い出してほしい)。

これら 63 文字のいずれか 1 つに結合記号が続く場合に限り、 ケースフォールディングの前に正準分解を適用しないと、比較の不一致が生じる可能性がある。 このような文字列は正規化形式ではなく、「自然に」(キーボードや他の入力処理を通じて) 生成するのは困難である。

たとえば、合成済み(NFC)文字 [U+1F8C GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI](これは、この基底文字と発音区別記号の組み合わせを 表す最も一般的な方法である)から始め、ケースフォールド変換だけを実行すると、最終的に ἄι [U+1F04 GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA + U+03B9 GREEK SMALL LETTER IOTA] が得られる。

代わりに、同じ文字を表す完全分解済み(NFD)の列 ᾌ [U+0391 GREEK CAPITAL LETTER ALPHA + U+0313 COMBINING COMMA ABOVE + U+0301 COMBINING ACUTE ACCENT + U+0345 COMBINING GREEK YPOGEGRAMMENI] から始めると、最終的に ἄι [U+03B1 GREEK SMALL LETTER ALPHA + U+0313 COMBINING COMMA ABOVE + U+0301 COMBINING ACUTE ACCENT + U+03B9 GREEK SMALL LETTER IOTA] が得られる。この文字列を NFC に正規化すると、上の最初の例と同じ文字列が生成される。

これらの両方の場合において、鋭アクセントは末尾のイオタではなく、 アルファの基底文字に関連付けられる。

しかし、半合成済みの列 ᾌ [U+1F88 GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI + U+0301 COMBINING ACUTE ACCENT] から始めると、最終的に ἀί [U+1F00 GREEK SMALL LETTER ALPHA WITH PSILI + U+03B9 GREEK SMALL LETTER IOTA + U+0301 COMBINING ACUTE ACCENT] が得られ、この場合、鋭アクセントはイオタに 関連付けられる。これは他のものと一致するように正規化できない列を生成する (また、元の利用者が知覚した文字とは異なる意味を持つため、実際には不正確である)。

上で述べたように、Unicode はケースフォールド操作を実行する前に テキストを NFD に正規化することで、この照合問題を解決する。すると [U+1F8C GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI]ᾌ [U+1F88 GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI + U+0301 COMBINING ACUTE ACCENT] は、どちらも分解済み版、すなわち ᾌ [U+0391 GREEK CAPITAL LETTER ALPHA + U+0313 COMBINING COMMA ABOVE + U+0301 COMBINING ACUTE ACCENT + U+0345 COMBINING GREEK YPOGEGRAMMENI] と同じになる。その列をケースフォールドして正規化すると、 すべての場合に一致するものが生成される。

2.5 文字エスケープとインクルード

ほとんどの文書形式またはプロトコルは、入力、処理、または 符号化が困難な文字を含めることを可能にするため、 エスケープ機構を提供している。これらのエスケープ機構は、 特定のリソース内で文字を表すための追加の等価な手段を提供する。 また、文書で使用される文字エンコーディング方式では表されない Unicode 文字を符号化することも可能にする。

注記

文字エスケープについてのさらなる議論、仕様における エスケープ機構の定義に関するガイドラインを含めて、次を参照のこと: [CHARMOD] の 4.6 節

注記

文字エスケープおよびインクルードの展開は文脈に依存する。すなわち、 文字列照合操作が実行されるときに、どの 構文的内容またはプログラミング言語が 適用されると見なされるかに依存する。su&#xE7;on を含むが suçon は含まない XML 文書で、文字列 suçon を検索する場合を考える。検索がプレーン テキストエディターで実行される場合、文脈は プレーンテキスト構文的内容やプログラミング言語は 適用されない)であり、&#xE7; 文字エスケープは認識されない。 したがって展開されず、検索は失敗する。検索が XML ブラウザーで実行される場合、 文脈は XML であり、文字エスケープ(XML によって定義される)は 展開され、検索は成功する。

中間的な場合として、エンティティ参照を展開しないまま XML 文書の表示を意図的に提供する XML エディターがある。 その場合、その擬似 XML 表示上での検索は、意図的にエンティティを 展開しない。その特定の文脈では、エンティティ参照は インクルードとは見なされず、展開する必要はない

たとえば、 U+20AC EURO SIGN は、HTML では 16 進エンティティ &#x20ac; または 10 進エンティティ &#8364; としても 符号化できる。JavaScript または JSON ファイルでは \u20ac または \u{20AC} として現れることができ、CSS スタイルシートでは \20ac として現れることができる。これらの表現はすべて、同じリテラル文字値 を符号化している。

文字エスケープは通常、文書が処理され、形式またはプロトコル内の 文字列が照合される前に解釈される。 上で使用した例に戻ると、次のようになる。

このテキストは次のように表示されると期待されるだろう: Hello world!

これを機能させるには、ユーザーエージェント(ブラウザー)は、CSS と HTML が それぞれ異なるエスケープ機構を使用しているにもかかわらず、クラス名 héllo を表す 2 つの文字列を照合しなければならなかった。上の断片は、 テキストが変異し得る一方で、仕様に従えばなお「同じ」と見なされ得る 1 つの方法を示している。 すなわち、クラス名 h\e9llo は HTML マークアップ内のクラス名 h&#xe9;llo と一致し(また、符号位置 é [U+00E9 LATIN SMALL LETTER E WITH ACUTE] を用いたリテラル値 héllo とも一致する)。

形式言語および文書形式は、あるリソース内に別のリソースからの テキストの一部を含めるための機能を提供することが多い。 インクルードとは、 リソースの本文に内容を挿入するための機構である。 インクルード機構は、処理時に内容をリソースへ取り込む。これは文書の構造に影響し、 場合によっては文書の語彙に対する照合にも影響する。インクルードの例には、 XML のエンティティ参照、XInclude [XInclude] 仕様、および CSS の @import 規則がある。

インクルードは、(文字エスケープの形式であれ、インクルードされたリソース内の文字リテラルであれ) 結合記号で始まらない場合、インクルード正規化済みであると言われる。

2.6 不可視 Unicode 文字

Unicode は、文書作成者がテキストの外観または機能を制御するのを 助ける、いくつかの特殊用途の文字を提供している。これらの文字の多くは 不可視であるか、キーボード上の対応物を持たないため、利用者は常に それらの存在または不在に気づくとは限らない。その結果、これらの文字が符号化された 文字列の一部である一方で、期待される照合テキストには含まれていない場合、 文字列照合を妨げることがある。これらの文字の例には、次のものが含まれる。

Unicode 制御文字 U+200D Zero Width JoinerZWJ とも呼ばれる)および U+200C Zero Width Non-JoinerZWNJ とも呼ばれる)。 これらの文字は、望ましくないリガチャの形成を防いだり、望ましいリガチャの形成を 促したりするなど、リガチャ形成を制御するために使用できるが、主な用途は、 アラビア文字やさまざまなインド系文字などの複雑な用字における 結合と字形選択を制御することである。一部のインド系文字では、作成者が 特定の結合文字が取る字形を制御できるようにするために、ZWJ および ZWNJ 文字を使用する。 [Unicode] の第 12 章の議論を参照。

Zero Width Non-Joiner は、ペルシア語で 特定の「通常の」アラビア文字の結合を防ぐために使用される。これらの場合、この文字の 存在または不在は意味に影響する。たとえば、語 تنها(「alone」)と語 تن‌ها (「bodies」 または「corpuses」)は、それぞれ "U+062A U+0646 U+0647 U+0627" および "U+062A U+0646 U+200C U+0647 U+0627" と符号化され、唯一の違いは後者の語における ZWNJ である。

ZWJ 文字は、特定の絵文字列の形成にも使用される。これについては 後述する。

異体字セレクター(U+FE00 から U+FE0F まで)は、 代替の外観またはグリフを選択するために使用される文字である (Character Model: Fundamentals [CHARMOD] を参照)。 たとえば、白黒絵文字とカラー絵文字を選択するために使用される。 これらは、事前定義された漢字異体字列(IVS)でも使用される。 Unicode Character Database(UCD)の "Standardized Variants" 部分に多くの例がある。

いくつかの用字は、視覚的変異選択を符号化する方法も提供している。その顕著な例は、 モンゴル文字の自由異体字セレクター(U+180B から U+180D まで)である。

U+034F Combining Grapheme Joiner という文字は、 その名称は誤解を招く(書記素を結合するものではない)が、ソートの目的で 本来は書記素と見なされ得る文字を分離するため、または Unicode 正規化をテキストに適用する際に特定のテキスト上の区別を維持する手段を 提供するために使用される。

空白の変異も、テキストの解釈および照合に影響する可能性がある。 たとえば、NBSP、NNBSP などのさまざまな改行不可空白文字である。

U+200B Zero Width Space は、空白が 通常現れないテキスト内で単語境界を示すために使用される文字である。 たとえば、タイ語の文書で単語分割を支援するために使用されることがある。

U+00AD Soft Hyphen は、テキスト内で 潜在的または推奨されるハイフネーション位置を示すために使用できる。 テキストがその位置で折り返されるよう再整形された場合にのみ可視になる。

U+2060 WORD JOINER は、時に WJ と呼ばれる、 ゼロ幅の改行不可空白文字である。その目的は、2 つの文字の間で改行が起こるのを 防ぐことである。改行目的を除いて、これは無視されるべきである。これは U+FEFF ZERO WIDTH NO-BREAK SPACE の置き換えとして機能する。 なぜなら U+FEFF は、より一般的に "Byte Order Mark"(BOM)として知られているからである。 バイト順マークは、一部のプレーンテキストファイルの先頭で、そのファイルが Unicode 文字 エンコーディングであることを示すために使用される。

最後に、ほとんどの用字は、横書きされる場合、左から右へ進む。しかし、アラビア文字や ヘブライ文字など一部の用字は、主に右から左へ書かれる。テキストはこれらの用字を 混在させて書かれることがあり、また、数値や別用字の引用符のように、テキストの他の部分と 反対方向に進む文字列を含むこともある。このようなテキスト方向の混在は、 双方向テキスト、略して bidi と呼ばれる。Unicode Bidirectional Algorithm [UAX9] は、 このような混在方向のテキストが表示のためにどのように処理されるかを説明している。 ほとんどのテキストでは、方向処理はテキスト自体から導き出すことができる。しかし、 テキストを正しく表示するために、アルゴリズムが追加情報を必要とする場合も多い。 さらなる例については、[html-bidi] を参照。

Unicode がテキスト方向の曖昧さに対処するために定義している方法の 1 つは、 方向ランの開始と終了を示す不可視の制御文字の集合である。 双方向制御は、(Unicode Bidirectional Algorithm がテキストの表示を助けるため) テキストの外観に影響を与えることがある一方で、制御がなくてもテキストが自然に 双方向ランに分かれる場合には、テキストに影響を与えないこともある。これらの制御文字は、 上述の文字と同様に不可視であるため、照合に意図しない影響を与える可能性がある。

これらのほぼすべての場合において、利用者は、特定の文書またはテキスト文字列が これらの文字のいずれかを含めているか、省略しているかに気づかない、または 確信できない場合がある。テキスト照合は基礎となる符号位置の一致に依存するため、 これらのマーカーによるテキストの符号化の変異は、(利用者の視点から見れば) 成功するはずの照合が不可解に失敗する原因となり得る。

2.7 絵文字列

Unicode の比較的新しい機能の 1 つが絵文字である。[UTR51] では、 Unicode はこれらを次のように説明している。

絵文字は、通常はカラフルな漫画風の形で提示され、テキスト内にインラインで 使用される絵記号(図的記号)である。顔、天気、乗り物と建物、 食べ物と飲み物、動物と植物、または感情、気持ち、活動を表すアイコンなどを表す。

絵文字は、U+200D ZERO WIDTH JOINER または ZWJ を含むさまざまな絵文字修飾子とともに使用して、 より複雑な絵文字を形成できる。

たとえば、絵文字(👪 [U+1F46A FAMILY])は、絵文字の間に ZWJ を用いた列 U+1F468 U+200D U+1F469 U+200D U+1F466 によっても形成できる。 他の絵文字を変更または追加すると、家族の構成を変えることができる。たとえば、列 👨‍👩‍👧‍👧 U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F467 は、この種の 合成をサポートするシステム上で、「family: man, woman, girl, girl」に対応する 合成絵文字を生じる。多くの一般的な絵文字は、ZWJ 列を使用することでのみ 形成できる。詳細については、[UTR51] を参照。

絵文字には、絵文字修飾文字を続けることができる。これらの修飾子は、人を表す絵文字について 肌の色を選択できるようにする。これらの文字は通常、それらが修飾する基底絵文字に続く 不可視の修飾子である。たとえば: 👨 👨🏻 👨🏼 👨🏽 👨🏾 👨🏿

絵文字には、基底絵文字のテキスト(白黒、 U+FE0E Variation Selector 15 によって示される)またはカラー (U+FE0F Variation Selector 16 によって示される)表示を示すために、 異体字 セレクターを続けることもできる。

絵文字の使用におけるさらに別の複雑な点は旗である。国旗は、 [BCP47] レジストリに由来する国コードを用いて 合成できる。たとえば、列 🇿 [U+1F1FF REGIONAL INDICATOR SYMBOL LETTER Z] 🇲 [U+1F1F2 REGIONAL INDICATOR SYMBOL LETTER M] は、ザンビアの 国コード(ZM)である 🇿🇲 を表す。その他の地域旗または特殊目的の旗は、 旗絵文字とさまざまな記号、または cancel tag で終わる地域指示コードを用いて 合成できる。たとえば、スコットランドの旗(🏴)は次のように合成できる。

これらの各機構は併用できるため、かなり複雑な文字列を用いて、 単一の絵文字書記素または画像を形成できる。非常によく似た絵文字列であっても、 まったく同じ符号化列を使用しない場合がある。ほとんどの場合、上述の修飾子および 組み合わせは、エンドユーザーのキーボードによって生成される(そこでは単一の絵文字 「文字」として提示される)。この符号化オプションの多様性は、異なるベンダーが Unicode によって「交換用に推奨」された列のみを(かつ正確に)使用する範囲で、 部分的に対処されている。これにより、ベンダーは、フォントとキーボードが利用者の期待する オプションを提供できるよう準備されていることを確保しやすくなる。それでも、利用者は一般に 基礎となる符号化の複雑さに気づかず、生成機構も推奨されたものに限定されない。 絵文字列は急速に進化しているため、近い将来、絵文字の照合を助ける、または妨げる 追加の発展がある可能性がある。Unicode 正規化は、これらの列を並べ替えたり、 修飾子を挿入または削除したりしない。したがって、利用者と実装者は、 名前空間やその他の照合文脈で絵文字を用いる利用者が、符号化の変異により、 予期しない「文字」の不一致に容易に遭遇し得ることに注意すべきである。

2.8 レガシー文字エンコーディング

リソースは、Web 上で文書形式を直列化するために、 レガシー文字エンコーディングを含む 異なる文字エンコーディング方式を使用できる。各文字エンコーディング方式は、 Universal Character Set の特定の部分集合を表すために、異なるバイト値および列を使用する。

注記

すべての文書、形式、およびプロトコルについて、UTF-8 などの Unicode 文字エンコーディングを 選択することは、強く推奨される 推奨事項である。 レガシー文字エンコーディングを使用しても追加の有用性はなく、この節の残りで述べる 考慮事項を完全に避けられるためである。

たとえば、 [U+20AC EURO SIGN] は、UTF-8 文字エンコーディングでは バイト列 0xE2.82.AC として符号化される。この同じ文字は、 レガシー文字エンコーディング windows-1252 では バイト列 0x80 として符号化される。 (他のレガシー文字エンコーディングでは、この文字を符号化するための バイト列をまったく提供しない場合がある。)

仕様は主に、文書の文字エンコーディング(レガシー文字エンコーディングであれ、 UTF-8 のような Unicode エンコーディングであれ)から変換した後、 さらに文書処理に進む前に文字エスケープを解除した後の、各文書を Unicode 文字の列と見なすことで、これらの結果として生じる変異に対処する。

注記

単一のレガシー文字エンコーディング内であっても、 実装に変異が存在することがある。有名な例の 1 つは、日本語のレガシー エンコーディング Shift_JIS である。異なる トランスコーダ実装は、特定のバイト列を Unicode にどのようにマップするかについて 選択に直面した。そのため、バイト列 0x80.60 (JIS X 0208 文字集合では 0x2141)は、ある実装では U+301C WAVE DASH にマップされ、他の実装では U+FF5E FULL WIDTH TILDE が選択された。これは、合理的で自己一貫した 2 つの トランスコーダが、同じ入力から異なる Unicode 文字列を生成し得ることを意味する。 Encoding [Encoding] 仕様は、部分的には Web 実装が相互運用可能で同一のマッピングを使用することを 確保するために存在している。しかし、Encoding 仕様と整合するトランスコーダが、 Web 上で見つかる文書や、特定の文書形式またはプロトコルに現れるデータの処理に 適用される保証はない。

Unicode への変換における追加の考慮事項の 1 つは、ヘブライ語やアラビア語などの 双方向用字のレガシー文字エンコーディングで、視覚的格納順序を使用するものが 存在することである。すなわち、Unicode や他の現代的なエンコーディングとは異なり、 文字は(ラインプリンターの場合のように)画面上に左から右へ印字される順序で メモリに格納される。これらのエンコーディングを Unicode に変換する場合、または これらのエンコーディング内でテキストを比較する場合、ソースとターゲットの両方の テキストを論理順序に置くよう注意しなければならない。詳細については、 [CHARMOD] の 3.3.1 節を参照。

2.9 その他の等価性の種類

注記

自然言語の検索または「検索」機能を実行する場合に適切となる、 追加の種類の等価性または処理が存在する。これらは、Character Model シリーズ文書の 別の部分([STRING-SEARCH])で 説明されている。 語彙の仕様、または形式構文で使用する照合アルゴリズムを 定義する仕様は、その文書で説明されているような追加の独自フォールディング、 マッピング、または処理を適用しようとすることを避けるべきである (SHOULD)。これは、それらが一貫した予測可能な結果の生成を 妨げるためである。

3. 文書形式およびプロトコルにおける構文的内容の文字列照合

Web 環境では、文字列が異なる文字エンコーディングを使用し、それらのエンコーディング内で異なる 文字列を使用し、この文書で説明する(大文字小文字などの)その他の変異を持ち得るため、 文字列の同一性を評価するための一貫した処理を確立することが重要である。

この章では、構文的 内容における文字列照合を指定および実装するための要件を定義する。

3.1 内容制限の指定

文字列照合をより効果的で一貫したものにする方法の 1 つは、照合対象となる内容に 制限を適用することである。語彙の定義、 特にその語彙内で ユーザー提供値を許可するものには、必然的に 何が「有効な識別子」を構成するかについての規則が含まれる。これには通常、長さと内容の 制限が含まれる。これらの制限を定義するためのベストプラクティスには、次のものが含まれる。

§

仕様は、識別子でサロゲート符号位置 (U+D800 から U+DFFF)または非文字符号 位置を許可するべきではない(SHOULD NOT)。

§

仕様は、識別子で C0U+0000 から U+001F)および C1U+0080 から U+009F)制御文字を 許可するべきではない(SHOULD NOT)。

識別子には大きく 2 つの種類がある。ユーザー向け識別子アプリケーション内部識別子である。

アプリケーション内部識別子は、文書形式または プロトコルの 語彙のうち、機械可読であり表示を意図しない部分である。 これらは、文書形式またはプロトコルの内容を扱ったりデバッグしたりする必要がある 開発者またはコンテンツ作成者の便宜のため、意味のある名前(一般に英語)を与えられることが多い。

§

アプリケーション内部識別子(利用者には決して 表示されず、常にアプリケーションまたはプロトコル内での照合または処理に使用されるもの)を 定義する仕様は、その内容を ASCII の印字可能な部分集合に制限するべきである (SHOULD)。ASCII の大文字小文字を区別しない照合が 推奨される(RECOMMENDED)。

§

アプリケーション内部 識別子のフィールドまたは値は、エンドユーザーに表示される場合、ローカライズ可能な 表示値で包まれなければならない(MUST)。

ユーザー向け識別子は、文書形式または プロトコルの 語彙のうち、利用者によって割り当てられる、または編集される、 あるいは選択のために利用者に提示される部分である。ユーザー向け識別子の例には、 ネットワーク名(SSID など)、デバイス名、クラス名、スタイル名、属性名、または ユーザー定義の設定や値が含まれる。この種の識別子は、この文書で説明する問題により 照合がより複雑になるが、特に英語を話さない利用者やラテン文字にあまり馴染みのない 利用者にとって、最良の体験を提供する。

多くの ユーザー向け識別子は、同時に ユーザー提供値でもあり、文書形式または プロトコルの利用者によって割り当てられ得る。利用者または利用者のコミュニティや文化が好む 自然言語を使用できることは、優れた利用者体験を提供し、特に英語において言語能力が限られている 可能性のある読者にとって機能をより利用しやすくする。

§

識別子が利用者に見える、または潜在的に見える場合、仕様は すべての言語の利用者が結果として得られる文書形式またはプロトコルを等しく利用できるようにするため、 非 ASCII Unicode 文字の使用を許可するべきである(SHOULD)。大文字小文字を区別すること(すなわちケースフォールディングなし)が 推奨される(RECOMMENDED)。

広範囲の Unicode 文字を許可するべきではあるが、仕様は ユーザー向け識別子の内容に 一定の実用的な制限を課すことができる。この種の内容規則を定義する仕様の一例は、 Unicode Identifier and Pattern Syntax [UAX31] に見られる。

3.2 照合アルゴリズムの選択

特定の仕様で使用する照合アルゴリズムを選択するための基本的な判断は、照合される 文字列に適用するテキスト正規化(大文字小文字の扱いと Unicode 正規化の両方を含む)の レベルである。歴史的に Web 上のほとんどの仕様は、Unicode 正規化なしの 大文字小文字を区別する照合を選んできており、これはすべての新しい仕様に対して 推奨される(RECOMMENDED)照合形式である。しかし、 大文字小文字を区別しないことや正規化が有用な場合もある。

仕様は、対象となる形式またはプロトコルの利用者にとっての利益が、実装のコストと 複雑さを上回る場合、大文字小文字を区別しないことを選択できる。ケースフォールディングと 正規化はどちらも、比較される値、すなわちテキストの表示、場合によっては意味にも影響を 与える可能性があり、またこれらの操作は比較的高コストであるため、大文字小文字を 区別しないことの選択は一般に推奨されない。

大文字小文字を区別しないことの特殊な場合として、ASCII/Basic Latin 範囲(すなわち 符号位置 U+0000 から U+007F)に 制限された語彙がある。これらの仕様は、その文字範囲に限って大文字小文字を区別しないことを 選択できる。これにより照合の実装は大幅に簡単になる。しかし、この形式の照合は、 識別子または構文でより広い範囲の Unicode を許可する仕様には適切ではない。なぜなら、 利用者が照合の振る舞いを理解しにくく、非 ASCII の用字および言語の利用者にとって 不利になるからである。すなわち、greenGREEN に一致するのに、grüßGRÜẞ または場合によっては GRÜSS に一致せず (代わりに GRüß に一致する)場合、利用者はそれを奇妙で予測不能だと感じる。

3.2.1 照合アルゴリズム

照合アルゴリズムは、2 つの文字列を比較するために必要な一連の手順を説明する。

  1. 比較する文字列を Unicode 符号位置の列に変換する。これには、レガシー文字エンコーディングからの トランスコードが伴う場合がある。
  2. すべての文字エスケープとインクルードを展開する。
  3. 適切な正規化ステップを実行する。
  4. 仕様に固有の追加の照合調整を実行する。
  5. 結果として得られる符号位置列を同一性について比較する。

3.2.2 適切な 正規化ステップの実行

注記

特定の仕様に適したテキスト正規化は、その形式またはプロトコルの語彙における要件に 依存する。テキスト正規化には 4 つの選択肢がある。

  1. 既定。 この正規化ステップはテキストに影響を与えず、その結果、 大文字小文字と Unicode 正規化の両方に関する形式の違いに敏感である。
  2. ASCII ケースフォールド。 ASCII(Basic Latin、 U+0000 から U+007F) 範囲で文字がケースフォールドされたテキストの比較。
  3. Unicode 正準ケースフォールド。 ケースフォールドされ、かつ Unicode 正準正規化が適用されたテキストの比較。
  4. Unicode 互換ケースフォールド。 ケースフォールドされ、かつ Unicode 互換正規化が適用されたテキストの比較。
3.2.2.1 既定の正規化 ステップ
§

識別子および構文的内容で文字列を照合する際、内容に対してケースフォールディングも Unicode 正規化も行わないことが推奨される(RECOMMENDED)。

この正規化ステップはテキストに影響を与えず、その結果、比較は、比較されるソース文字列における 大文字小文字と Unicode 正規化形式の両方の違いに敏感である。コンテンツ作成者は、 トークンの一致を期待する場合、影響を受けるテキストを符号化するために一貫した 大文字小文字と一貫した文字列を使用していることを認識し、確保する必要がある。

3.2.2.2 ASCII ケース フォールド正規化ステップ
§

「ASCII ケース フォールド」手法は、それ自体が ASCII 範囲に制限されている語彙 (または照合が ASCII トークン上でのみ発生する場合)について、例外的な場合にのみ 使用するべきである。

ASCII ケースフォールド正規化ステップは、ASCII 範囲についてのみケースフォールディングを行う。 Unicode 正規化形式は適用されない。このステップは、それ自体が ASCII 範囲に制限されている 語彙(または照合が ASCII トークン上でのみ発生する場合)にのみ適切である。

各文字列について、次の手順を実行する。

  1. 文字列内の各 Unicode 符号位置について、その符号位置が U+0041 LATIN CAPITAL LETTER A から U+005A LATIN CAPITAL LETTER Z まで(両端を含む)の間にある場合、 U+0061 LATIN LOWERCASE LETTER A から U+007A LATIN LOWERCASE LETTER Z までの対応する符号位置に置き換え、それ以外の場合は元の符号位置を保持する。
  2. 結果として得られる文字列を返す。
3.2.2.3 Unicode 正準ケースフォールド正規化ステップ
§

大文字小文字を区別しないことは、ほとんどの仕様には推奨されないが、 語彙が非 ASCII 文字を許可し、かつ大文字小文字の区別に敏感でありたくない例外的な場合には、 「Unicode 正準ケースフォールド」手法を使用するべきである (SHOULD)。

非 ASCII 文字を許可する 語彙を持つ仕様には、ほとんどの新しい語彙が 含まれるべきである。

Unicode ケースフォールディングは非正規化文字列を生成し得るため、照合が利用者の期待と 一貫するようにするには、任意の Unicode ケースフォールドの後に Unicode 正規化を 行う必要がある。例については、§ 2.4 正規化とケースフォールディングの相互作用を参照。

注記

[Unicode] の要件 D145 は、 結果の文字列が正規化形式になることを確保するために、ケースフォールド操作の後に正規化ステップを 要求している。ケースフォールド後の正規化を含めることは 任意である。結果の文字列が比較のためだけに使われ、 保存または利用者に表示されない場合、ケースフォールド後の符号位置列は等価になる。 ただし、それらが特定の正規化形式にあることは保証されない。これは D145 の 意図的違反である。Unicode は、これが有効な推奨であることを確認している。

各文字列について、次の手順を実行する。

  1. 文字列を NFD 形式または NFC 形式へ Unicode 正規化する。
  2. 結果として得られた文字列に Unicode Full ケースフォールディングを実行する。
  3. [OPTIONAL] 結果として得られた文字列を NFC 形式へ Unicode 正規化する。これにより、 利用者に表示するために文字列が正規化形式であることが保証される。
  4. 結果を返す。
3.2.2.4 Unicode 互換ケースフォールド正規化ステップ
§

「Unicode 互換ケースフォールド」手法は使用するべきではない。

非 ASCII 文字を許可し、かつ Unicode 互換等価なものを照合する必要がある語彙を持つ仕様は、 この正規化ステップを使用する場合がある。互換正規化形式(NFKC および NFKD)はテキストの意味、外観、および処理を変化させるため、 このステップは Web 上のほとんどのアプリケーションで使用するべきではない (SHOULD NOT)。

警告

ケースフォールディングは入力符号位置列の影響を受ける。また、非正規化の 符号位置列を生成することもある。互換分解とケースフォールディングの相互作用は、 一貫した一致を生成するために複数回の処理を必要とする。その結果、この正規化ステップには Unicode 正規化の複数回の使用が含まれる。例については、§ 2.4 正規化とケース フォールディングの相互作用を参照。

各文字列について、次の手順を実行する。

  1. 文字列を NFD 形式へ Unicode 正規化するまたは、影響を受ける 63 個のギリシャ文字のマッピングを実行する。
  2. 結果として得られた文字列に Unicode Full ケースフォールディングを実行する。
  3. 結果として得られた文字列を NFKD 形式へ Unicode 正規化する。
  4. 結果として得られた文字列に Unicode Full ケースフォールディングを実行する。 (これにより、互換マッピングによって生成された副産物が取り除かれる。)
  5. [OPTIONAL] 結果として得られた文字列を NFKC 形式へ Unicode 正規化する。(これにより、符号位置列が表示のために正規化されることが保証される。)
  6. 結果を返す。

3.2.3 Unicode 符号位置の列への変換

§

コンテンツ作成者は、リソースを Unicode 文字エンコーディング (Web では一般に UTF-8)で入力し保存するべきである(SHOULD)。

テキストを比較する最初の手順は、両方が同じデジタル表現を使用していることを確保することである。 これは、実装が レガシー 文字エンコーディング内の任意のテキストを Unicode 符号位置の列に変換する必要があることを意味する。 通常これは、トランスコーダを適用して、データを一貫した Unicode エンコーディング形式(UTF-8 や UTF-16 など)へ変換することによって行われる。これにより、 文字列の等価性を判断するために文字列をビット単位で比較できる。

§

コンテンツ作成者は、特定の文字のマッピングが意味を妨げる場合を除き、 レガシー符号化されたテキストまたはリソースを Unicode に変換する際、 正規化トランスコーダを選択するべきである (SHOULD)。

正規化トランスコーダとは、 トランスコーダであり、 レガシー文字エンコーディングから Unicode への変換を実行し、かつ結果が Unicode 正規化形式 C(NFC)になることを確保するものである。ほとんどの レガシー文字エンコーディングについては、(任意のトランスコーダに正規化器を続けることで) 正規化トランスコーダを構築することが可能である。レガシー文字 エンコーディングレパートリが Unicode で表されていない文字を含む場合は、そうすることはできない。正規化トランスコーダは NFC にある文字列だけを生成するが、変換された 文字列は インクルード正規化済みではない場合がある (たとえば、結合記号で始まる場合)。

Web 上の文書形式は、追加の外部リソース(たとえば、HTML 文書に適用される CSS スタイルシート)と 相互作用したり、それらを用いて処理されたりすることが多いため、異なる文字エンコーディングを 使用する文書間で値を照合する際、テキストの一貫した表現が重要になる。正規化トランスコーダの 使用は、レガシー符号化文書を、ほとんどの言語で通常期待される Unicode 文字列に一致させることで、 相互運用性を確保するのに役立つ。

Web で使用されるほとんどのトランスコーダは、出力として NFC を生成するが、いくつかはそうではない。 これは通常、トランスコーダを元のレガシー文字エンコーディングと往復互換にするため、 他の文字上の区別を保持するため、またはユーザーエージェントで使用されている他の トランスコーダと一貫させるためである。これは、Encoding 仕様 [Encoding] およびその他のさまざまな重要な トランスコード実装に、非正規化トランスコーダがいくつも含まれることを意味する。 実際、Unicode における互換文字のほとんどは、レガシーエンコーディングからの往復変換のためだけに 存在しており、それらの多くは NFC において 単一対応の正準マッピングを持つ。この例は、この文書の前の箇所 [U+212B ANGSTROM SIGN] を用いて見た。

ほとんどのトランスコーダが NFC 出力を生成し、 すべての文字について NFC を生成しない トランスコーダでさえ、大多数の文字については NFC を 生成することに留意すること。特に、合成済み形式が存在する箇所で分解形式を生成する、 または正規化された列とは異なる結合文字列を生成する、一般的に使用されるトランスコーダは 存在しない(そしてこれは [Encoding] にあるトランスコーダのすべてに当てはまる)。

§

仕様は、Unicode 文字エンコーディングを許可しなければならない (MUST)。

§

仕様は、既定の文字エンコーディングを指定しなければならず (MUST)、既定のエンコーディングとして UTF-8 を指定するべきである (SHOULD)。

§

仕様は、UTF-8 以外のエンコーディングを禁止するべきである (SHOULD)。

レガシー文字エンコーディングは、一般に Web 上での有用性を失っている。新しい仕様は、最初から Unicode エンコーディングをサポートし、 Unicode エンコーディング(一般に UTF-8)を既定とし、可能であれば、その他の エンコーディングの使用を禁止する必要がある。これは相互運用性を促進するだけでなく、 文字およびデータ表現における無意味な変異の範囲を縮小する。

3.2.4 文字エスケープと インクルードの展開

ほとんどの文書形式およびプロトコルは、文字をエスケープ列として符号化する手段、 またはテキストを含む外部データを リソースへ含める手段を提供する。 これは、[CHARMOD] の 4.6 節、および上記で詳しく議論されている。

照合を実行する際、文字エスケープをいつ解釈すべきかを知ることは、一致が適切に 成功(または失敗)するようにするために重要である。通常、エスケープ、参照、および インクルードは、照合(または照合に敏感な処理)を実行する前に処理または展開される。 なぜなら、これらの構文は、符号化が困難な列を文書へ便利に入れることを可能にしつつ、 対象の文書内で直接符号位置列として符号化されたかのように文字が振る舞うことを 可能にするために存在するからである。

これが複雑になり得る領域の 1 つは、構文的 内容ローカライズ可能な内容がどのように相互作用するかを 決定することである。たとえば、次の HTML 断片を考える。

技術的には結合記号  ̀ [U+0300 COMBINING GRAVE ACCENT​] は直前の引用符と結合するが、 HTML は、この文字(エンティティとして符号化されているかどうかにかかわらず)を HTML 構文の一部とは 見なさない。

リソース上で照合操作を実行する場合、一般的な規則は、利用者が相互作用しているのと同じ 「レベル」でエスケープを展開することである。たとえば、上の例を考える場合、HTML の ソースを表示するツールは、エスケープ列 &#x300; をアンパサンドで始まる 文字列として表示する。対照的に JavaScript プログラムは、ブラウザーによる文書の解釈上で 動作し、属性 id の値として文字 U+0300 を照合する。

文書形式の構文を処理する場合、エスケープは通常、その形式の処理規則によって明示的に 禁止されている場合を除き、構文の処理前に、それが表す文字列へ変換される。これにより、 リソースはあらゆる種類の文字をそのリソースの構文構造に含めることができる。

場合によっては、エスケープの前処理が問題を生じる。たとえば、HTML 文書を解析する前に 列 &lt; を展開すると、文書エラーが発生する。

3.2.5 正規化に関する 追加の考慮事項

特定の Unicode 正規化形式が、コンテンツ作成者にとって常に適切または利用可能であるとは 限らず、利用者のテキスト符号化の選択が、データの下流の消費者にとって明白でない場合もある。 この文書で示すように、コンテンツ作成者またはアプリケーションがテキストを入力または交換する際、 同じ意味的値を表すために選択し得る方法は多数存在する。正規化は、利用者が意図的に適用した 区別を取り除く可能性がある。したがって、照合アルゴリズムは、文字列のケースフォールド照合を行う際に Unicode 正規化を使用することを指定しており、それもアルゴリズム内部に限られる。 内容に正規化を課すことは、利用者および実装者にとって障壁となり得る。したがって:

§

仕様は、特定の語彙の符号化、保存、または交換のために Unicode 正規化形式を指定するべきではない(SHOULD NOT)。

§

実装は、内容を Unicode 文字エンコーディングへトランスコードすること、 ケースフォールディング、またはその他の利用者が開始した変更など、テキスト変換の副作用として そうする必要がある場合を除き、交換、読み取り、解析、または処理される構文的内容 (ユーザー提供値を含む)またはローカライズ可能な内容の正規化形式を変更してはならない (MUST NOT)。消費者または内容自体が非正規化表現に依存している 可能性があるためである。

§

作成ツールは、リソースを正規化する手段を提供し、特定のリソースが Unicode 正規化形式 C でない場合に利用者へ警告するべきである (SHOULD)。

注記

特定の正規化形式でのテキストの保存および交換を要求する仕様は、 § 3.2.5.1 文書形式で正規化を指定する際の 要件にある要件に対処する必要がある。

仕様は、追加要件が必要である明確で具体的な理由がない限り、形式またはプロトコルに対して 正規化形式でデータを保存または交換することを要求することは、一般に推奨されない。Web 上の 多くの文書形式は正規化を要求しないため、コンテンツ作成者は時折、非正規化文字列に依存している 可能性がある。正規化ステップは、そのような内容に悪影響を与える可能性がある。

正準正規化形式(NFC 形式または NFD 形式)は、 適用されるテキストの意味と表示を保持することを意図している。これは常に当てはまるわけではなく、 それが正規化が推奨されない理由の 1 つである。NFC には、(単純に 1 対 1 で Unicode エンコーディングへ トランスコードされた場合の)ほぼすべてのレガシーデータ、ならびに現在のソフトウェアによって 作成されたデータ、またはほとんど(ただしすべてではない)のキーボードで利用者によって 入力されたデータが、すでにこの形式であるという利点がある。NFC はまた、わずかなコンパクトさの利点を持ち、 文字と書記素との関係に関して、ほとんどの言語で利用者の期待によりよく一致する。

§

仕様は、互換正規化形式(NFKC、NFKD)を指定するべきではない (SHOULD NOT)。

§

実装は、エンドユーザーによって明示的に要求されない限り、互換正規化形式 (NFKC、NFKD)を適用してはならない(MUST NOT)。

互換正規化形式(NFKC 形式および NFKD 形式)は、重要な方法でテキストの構造を変え、 意味を失わせる。利用者は、Unicode で互換マッピングを持つ文字を意図的に使用することがあり、 または Unicode に変換されたときに互換マッピングを持つレガシー文字エンコーディングの文字を 使用することがある。これはコンテンツ作成者の意図的な行為と見なす必要がある。 NFKC/NFKD は、ローカライズ可能な内容に対する「検索」操作や文字列検索で有用な場合があるが、 互換上の違いを消去することは有害である。

注記

NFC を要求することは、仕様開発者の側に 追加の注意を必要とする。Web 上の内容は一般に既知の正規化状態にないためである。 非正規化内容に対する境界条件およびエラー条件は、このような場合には慎重に検討し、 十分に指定する必要がある。

§

正準等価だが互いに素な Unicode 文字列がセキュリティ上の問題を表す場合、 仕様はそれを文書化する、または警告を提供しなければならない (MUST)。

§

コンテンツ作成者は、可能な限り、内容に Unicode 正規化形式 C(NFC)を使用するべきである (SHOULD)。

NFC は、内容に常に適切であるとは限らず、 一部の言語ではコンテンツ作成者にとって利用可能でさえない場合があることに注意。

§

コンテンツ作成者は、形式または実装によって実行される照合に Unicode 正規化形式が含まれている場合でも、照合を容易にするため、常に一貫した Unicode 文字列を使用してテキストを符号化するべきである(SHOULD)。

内容が一貫して処理されるようにするため、コンテンツ作成者は同じテキストを表すために 一貫した符号位置列を使用するよう努めるべきである。内容はいかなる正規化形式であってもよく、 非正規化(ただし有効な)Unicode 文字列を使用する場合もあるが、表現の不一致は、実装が 異なる列を異なるものとして扱う原因となる。一貫した選択、アクセス、抽出、処理、または 表示を確保する最善の方法は、常に NFC を使用することである。

§

コンテンツ作成者は、リソース内で、先行する基底文字なしに結合記号を 含めるべきではない(SHOULD NOT)。

これには例外があり得る。たとえば、文字の一覧([Unicode] 文字の一覧など)を作る場合、 作成者は対応する基底文字なしに結合記号を使用したいことがある。しかし、基底文字なしに 結合記号を使用すると、単純な実装が結合記号を隣接する構文的内容、ユーザー提供内容、または ローカライズ可能な内容と結合してしまう場合など、意図しない表示または処理上の問題を引き起こす 可能性がある。たとえば、文字  ́ [U+0301 COMBINING ACUTE ACCENT​] のような結合記号を HTML の class 属性値の先頭として 使用すると、そのクラス名はエディターで適切に表示されず、編集しにくい場合がある。

推奨される基底文字には、 [U+25CC DOTTED CIRCLE](基底文字を可視にする必要がある場合)または   [U+00A0 NO-BREAK SPACE](基底文字を不可視にすべき場合)が含まれる。

コンテンツ作成者が常にこれらのガイドラインに従うとは限らないため:

§

語彙の仕様は、構文的内容と文字データの境界、および (その言語に何らかのインクルード機構がある場合は)エンティティ境界を定義しなければならない (MUST)。これらには、任意の文字を表現するための文字エスケープを 許可しつつ、その言語のインスタンスが処理されるときに、内容の処理または照合で 衝突を生じ得るあらゆる境界を含める必要がある。

3.2.5.1 文書形式で正規化を指定する際の要件

仕様が保存、伝送、または処理のために Unicode 正規化を要求する場合、仕様作成者および その仕様の実装者は、いくつかの追加の考慮事項に対処する必要がある。

§

操作が正規化されたテキスト入力から非正規化出力を生成し得る場合、 仕様は、結果として得られる出力が正規化される必要があるかどうかを定義しなければならない (MUST)。仕様は、一部の操作について正規化の実行を任意と 述べてもよい(MAY)。この場合、既定では正規化が実行される べきであり(SHOULD)、正規化を無効にするには明示的なオプションを 使用するべきである(SHOULD)。

§

正規化を要求する仕様は、正規化の実装を任意としてはならない (MUST NOT)。

一部の実装が正規化し、他の実装が正規化しない場合、相互運用性は達成できない。

正規化を実行することを要求される実装は、次の要件を考慮する必要がある。

§

正規化に敏感な操作は、実装が最初に検査によってテキストが正規化形式に あることを確認したか、または実装自身がテキストを再正規化した場合を除き、実行してはならない (MUST NOT)。これらの規則の対象とならない私的システム内では 私的合意を作成してもよい(MAY)が、外部から観察可能な結果は、規則に従った場合と 同じでなければならない(MUST)。

§

テキストを変更し、正規化に敏感な操作を実行する正規化テキスト処理コンポーネントは、 各変更の後に正規化が行われたかのように振る舞わなければならない (MUST)。これにより、その後の正規化に敏感な操作は常に、 正規化されたテキストを扱っているかのように振る舞う。

§

作成ツールの実装は、処理、表示、または交換を妨げる可能性のある 結合記号で始まる構文的内容の入力または作成について、利用者に警告する、または防止する べきである(SHOULD)。

3.2.6 ケース フォールディングに関する追加の考慮事項

文字列同一性照合における重要な考慮事項の 1 つは、比較が大文字小文字を区別するか 区別しないかである。

§

コンテンツ作成者は、形式または実装でケースフォールド照合がサポートされている場合でも、 照合を容易にするため、常に識別子を一貫した大文字、小文字、および混在ケースの形式で 綴るべきである(SHOULD)。

3.2.6.1 大文字小文字を区別する照合
§

ユーザー定義値を含む構文的内容の照合には、大文字小文字を 区別する照合が推奨される(RECOMMENDED)。

語彙は通常、コンテンツ作成者および利用者にとっての予測可能性を重視する。 大文字小文字を区別する照合は最も実装しやすく、通常は基礎となる Unicode 符号位置列の 比較で構成されるため、混乱を招く可能性が最も低い。これは言語固有のケースマッピングなどの 考慮事項の影響を受けないため、構文的内容に上記の トルコ語の例のような語を含めた文書作成者に対して、 最も驚きの少ない結果を生む。

大文字小文字を区別しないことは通常、ローカライズ可能な 内容の処理、たとえば 自然言語テキスト検索の実行のために 予約される。しかし、大文字小文字を区別しないことが望ましい場合もある。このような場合には、 形式言語が考慮する必要があるいくつかの実装上の選択肢がある。

3.2.6.2 Unicode の 大文字小文字を区別しない照合
§

Unicode の Basic Latin(ASCII)範囲を超えるものを含む語彙で 大文字小文字を区別しない照合を定義する仕様は、 Unicode full ケースフォールド照合を指定しなければならない (MUST)。

§

仕様は、ユーザー定義値について Unicode の全範囲を許可するべきである (SHOULD)。

語彙は一般に、特に ユーザー提供値について、広範囲の Unicode 文字を 許可するべきである。これは、不利益なしに最も広い範囲の言語と文化による利用を 可能にするためである。その結果、ケースフォールディングなどのテキスト操作は、選択された部分だけでなく Unicode の全範囲に対処する必要がある。大文字小文字を区別しない照合が望まれる場合、 これは Unicode ケースフォールディングを使用することを意味する。

Unicode simple ケースフォールディング形式は、 Web 上の文字列同一性照合には適切ではない。

3.2.6.3 ASCII の 大文字小文字を区別しない照合
§

Unicode の Basic Latin(ASCII)部分集合に制限された語彙で 大文字小文字を区別しない照合を定義する仕様は、 ASCII の大文字小文字を区別しない照合を指定してもよい (MAY)。

語彙が ASCII に制限され、ユーザー定義の名前や 識別子を許可しない形式言語は、ASCII の大文字小文字を区別しない照合を指定できる。この例として HTML があり、HTML 仕様によって 定義される要素名および属性名について、ASCII の大文字小文字を区別しない比較の使用を定義している。

語彙が「ASCII のみ」と見なされるのは、すべてのトークンと識別子が仕様によって 直接定義され、これらの識別子またはトークンが Unicode の Basic Latin 部分集合だけを 使用する場合、かつその場合に限られる。ユーザー定義識別子が許可される場合、 (セキュリティまたは交換上の懸念に応じて適切に制限されるが、[UTR36] を参照) Unicode 文字の全範囲が許可されるべきであり、同一性照合には Unicode の 大文字小文字を区別しない照合が使用されるべきである。

注記

ASCII のみの語彙は、識別子または値により広い範囲の Unicode を許可する 文書形式またはプロトコルの内部に存在し得る。たとえば [CSS-SYNTAX-3] は、CSS スタイルシートの形式を、識別子および値に Unicode の全範囲を使用できる方法で定義している。 しかし、CSS 仕様は常に CSS キーワードを ASCII 範囲の部分集合を用いて定義する。 したがって、多くのスタイルシートには ASCII ではない識別子またはデータ値が含まれるにもかかわらず、 CSS の語彙は ASCII のみである。

3.2.6.4 言語固有の 調整

ロケールまたは言語固有の調整は、自然言語処理操作の一部である場合に最も適切である (これはこの文書の範囲外である)。ケースマッピングまたはケースフォールディングの 言語固有の調整は、汎用のケースフォールディング規則とは異なる結果を生成するため、 予測可能性が重視される形式言語では避けるべきである。

§

語彙で大文字小文字を区別しない照合を定義する仕様は、言語依存の 大文字小文字を区別しない照合を指定するべきではない (SHOULD NOT)。

§

言語依存の大文字小文字を区別する照合が指定される場合、 Unicode ケースマッピングは言語に応じて調整されるべきであり (SHOULD)、各調整に使用される言語の出典は指定されなければならない (MUST)。

照合される 2 つの文字列は異なる言語である場合があり、さらに第 3 の言語文脈に 現れる場合もある。したがって、ケースフォールディングにどの言語を使用するかは、 アプリケーションと利用者の期待に依存する。

言語固有の調整は、言語情報を取得、検証、または管理することが困難であり得ること、 また、その結果として得られる操作が、利用者を困惑させる結果を生じたり、利用者が使用している 言語設定または照合が実行されるシステムの設定によって、一部の利用者では失敗し他の利用者では 成功する結果を生じたりする可能性があるため、形式言語には推奨されない。

§

言語固有の操作は、適切な場合には言語固有のケースフォールディングを 含めるべきである(SHOULD)。

たとえば、CSS の text-transform 操作は、文字列をケースマップする際に 言語依存である。

注記

Unicode ケースフォールディングは文書形式およびプロトコルに推奨される 大文字小文字を区別しない照合であるが、既定とは異なるマッピングを持つ言語の コンテンツ作成者および利用者は、自分たちの期待が一般に話す言語と一致しているため、 なお結果に驚くことがある。

注記

言語依存の文字列比較は、多くの場合 ロケール依存と呼ばれる。これは、ほとんどのプログラミング言語および オペレーティング環境が、それぞれのロケールベースの API を用いて言語固有の調整に アクセスするためである。たとえば、Java プログラミング言語の java.text.Collator クラス、または JavaScript の Intl.Collator を参照。

3.2.7 追加の照合調整

§

仕様は、照合処理の一部として行われる追加の調整を明確に定義しなければならない (MUST)。

一部の仕様は、特定の語彙における照合を支援するために、追加の調整を含めたい場合がある。 その例には、2 節で説明した追加のテキスト上の差異を取り除くこと、 構文の一部である文字をまとめてマッピングする、または取り除くこと、あるいは空白のトリムを 実行することが含まれる。

任意の追加の調整は、異なる言語が Unicode で表される方法を妨げないようにする必要がある。 たとえば、テキストを分解し、その後すべての結合文字を取り除くことで文字からアクセントを 削除しようとする処理は、結合記号に依存する言語を壊してしまう。この例として、 例 2のデーヴァナーガリー文字のテキストが挙げられる。 (このような処理は、潜在的なアクセントをすべて取り除くことにも失敗し、おそらく テキストの意味と表現を損なうことにもなる。)

4. その他の照合および 処理上の考慮事項

形式言語における文字列およびトークンの照合がこの文書の主な関心事であるが、 仕様が純粋な文字列等価性を超えた追加の種類の照合を考慮する必要がある場合もある。

4.1 正規表現

§

正規表現構文を定義する仕様は、[UTS18] に従い、 少なくとも Basic Unicode Level 1 サポートを提供しなければならず(MUST)、Extended または Tailored(Level 2 および 3)サポートを 提供するべきである(SHOULD)。

正規表現構文は、形式またはプロトコルを定義する際に有用な場合がある。これは、利用者が 部分的にしか分かっていない値、または予測可能な方法で変化し得る値を指定できるためである。 この文書の各節で見たように、文字を Unicode で符号化できる方法には変異があり、 これは式における文字列の指定方法または照合方法に影響を及ぼす可能性がある。 たとえば、文字数を数える際には、使用される Unicode 符号位置の数ではなく 書記素境界に依存する必要があるかもしれない。大文字小文字を区別しない照合では、 ケースフォールディングの変異を考慮する必要があるかもしれない。または、処理される式や テキストの Unicode 正規化を考慮する必要があるかもしれない。

Unicode Regular Expressions Level 1 サポートには、正規表現で Unicode 符号位置を 指定する機能(エスケープの使用によるものを含む)、Unicode 文字プロパティへのアクセス、 およびほとんどの正規表現構文に共通する特定の種類の境界へのアクセスが含まれる。

Level 2 はこれを拡張し、特定の種類の 書記素クラスタ境界でテキストを選択する機能や、 ケース変換のサポート(上で広く言及した 2 つのトピック)など、多くの重要な機能を提供する。 Level 3 は、ロケール [LTLI] に基づく 正規表現の調整を提供する。これは形式言語ではあまり有用ではないが、 ローカライズ可能な内容の処理では有用な場合がある。

A. 前回公開バージョン以降の変更点

この文書の変更点(2018-04-20 の Working Draft 以降)は、github コミットログで確認できる。

このバージョンでは、Unicode 正準ケースフォールド正規化ステップおよび Unicode 互換ケースフォールド正規化ステップにおいて、 どの正規化ステップが任意であるかを変更している。このバージョンは、最初のステップとして 正規化を要求し、出力の正規化を任意にしている。この変更は、テストおよび Unicode との 議論に基づいている。

B. 謝辞

W3C Internationalization Working Group および Interest Group、 ならびにその他の人々から、多くのコメントと提案が寄せられた。Working Group は次の方々に感謝する。 Mati Allouche、 Ebrahim Byagowi、 John Cowan、 Martin Dürst、 Behdad Esfahbod、 Asmus Freitag、 Richard Ishida、 John Klensin、 Peter Saint-Andre、 Amir Sarabadani、 Najib Tounsi、 Richard Wordingham、 そしてこの文書の 20 年(!!)にわたる開発に携わったすべての CharMod 貢献者。

この文書の前のバージョンは、次の人々によって編集された。

C. 参考文献

C.1 規範的参考文献

[ASCII]
ISO/IEC 646:1991, Information technology -- ISO 7-bit coded character set for information interchange. URL: http://www.ecma-international.org/publications/standards/Ecma-006.htm
[BCP47]
Tags for Identifying Languages. A. Phillips, Ed.; M. Davis, Ed.. IETF. 2009年9月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc5646
[CHARMOD]
Character Model for the World Wide Web 1.0: Fundamentals. Martin Dürst; François Yergeau; Richard Ishida; Misha Wolf; Tex Texin et al. W3C. 2005年2月15日. W3C Recommendation. URL: https://www.w3.org/TR/charmod/
[CHARREQ]
Requirements for String Identity Matching and String Indexing. Martin Dürst. W3C. 2009年9月15日. W3C Note. URL: https://www.w3.org/TR/charreq/
[Encoding]
Encoding. Anne van Kesteren; Joshua Bell; Addison Phillips. URL: https://www.w3.org/TR/encoding/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[html-bidi]
Additional Requirements for Bidi in HTML & CSS. Aharon Lanin; Richard Ishida. W3C. 2015年7月21日. W3C Note. URL: https://www.w3.org/TR/html-bidi/
[INFRA]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[INTERNATIONAL-SPECS]
Internationalization Best Practices for Spec Developers. Richard Ishida; Addison Phillips. W3C. 2021年3月25日. W3C Working Draft. URL: https://www.w3.org/TR/international-specs/
[ISO10646]
Information Technology - Universal Multiple- Octet Coded CharacterSet (UCS) - Part 1: Architecture and Basic Multilingual Plane. ISO/IEC10646-1:1993.
[LTLI]
Language Tags and Locale Identifiers for the World Wide Web. Addison Phillips. W3C. 2020年10月7日. W3C Working Draft. URL: https://www.w3.org/TR/ltli/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997年3月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. 2005年1月. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. 2017年5月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[UAX11]
Unicode Standard Annex #11: East Asian Width. Ken Lunde 小林劍. URL: https://www.unicode.org/reports/tr11/
[UAX15]
Unicode Normalization Forms. Ken Whistler. Unicode Consortium. 2020年2月24日. Unicode Standard Annex #15. URL: https://www.unicode.org/reports/tr15/tr15-50.html
[UAX29]
Unicode Standard Annex #29: Unicode Text Segmentation. Mark Davis. URL: https://www.unicode.org/reports/tr29/
[UAX31]
Unicode Identifier and Pattern Syntax. Mark Davis. Unicode Consortium. 2020年2月13日. Unicode Standard Annex #31. URL: https://www.unicode.org/reports/tr31/tr31-33.html
[UAX35]
Unicode Locale Data Markup Language (LDML). Mark Davis et al. Unicode Consortium. 2020年10月23日. Unicode Technical Standard #35. URL: https://www.unicode.org/reports/tr35/tr35-61/tr35.html
[UAX9]
Unicode Standard Annex #9: Unicode Bidirectional Algorithm. Mark Davis; Aharon Lahnin; Andrew Glass. URL: https://unicode.org/reports/tr9/
[Unicode]
The Unicode Standard. Unicode Consortium. URL: https://www.unicode.org/versions/latest/
[UTR36]
Unicode Technical Report #36: Unicode Security Considerations. Mark Davis; Michel Suignard. URL: https://www.unicode.org/reports/tr36/
[UTR50]
Unicode Technical Report #50: Unicode Vertical Text Layout. Koji Ishii 石井宏治. URL: https://www.unicode.org/reports/tr50/
[UTR51]
Unicode Technical Report #51: Unicode Emoji. Mark Davis; Peter Edberg. URL: https://www.unicode.org/reports/tr51/
[UTS18]
Unicode Technical Standard #18: Unicode Regular Expressions. Mark Davis; Andy Heninger. URL: https://unicode.org/reports/tr18/
[UTS39]
Unicode Technical Standard #39: Unicode Security Mechanisms. Mark Davis; Michel Suignard. URL: https://www.unicode.org/reports/tr39/
[XInclude]
XML Inclusions (XInclude) Version 1.0 (Second Edition). Jonathan Marsh; David Orchard; Daniel Veillard. W3C. 2006年11月15日. W3C Recommendation. URL: https://www.w3.org/TR/xinclude/

C.2 参考情報としての参考文献

[CSS-SYNTAX-3]
CSS Syntax Module Level 3. Tab Atkins Jr.; Simon Sapin. W3C. 2019年7月16日. W3C Candidate Recommendation. URL: https://www.w3.org/TR/css-syntax-3/
[STRING-META]
Strings on the Web: Language and Direction Metadata. Addison Phillips; Richard Ishida. W3C. 2019年6月11日. W3C Working Draft. URL: https://www.w3.org/TR/string-meta/
Character Model for the World Wide Web: String Searching. Addison Phillips. URL: https://w3c.github.io/string-search/
[XML10]
Extensible Markup Language (XML) 1.0 (Fifth Edition). Tim Bray; Jean Paoli; Michael Sperberg-McQueen; Eve Maler; François Yergeau et al. W3C. 2008年11月26日. W3C Recommendation. URL: https://www.w3.org/TR/xml/