CyberLibrarian

【注意】 このドキュメントは、W3CのCharacter Model for the World Wide Web: String Matching W3C Working Group Note 04 February 2019の和訳です。
このドキュメントの正式版はW3Cのサイト上にある英語版であり、このドキュメントには翻訳に起因する誤りがありえます。誤訳、誤植などのご指摘は、訳者までお願い致します。

First Update: 2019年6月11日


ウェブの文字モデル: 文字列マッチング

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

本バージョン:
https://www.w3.org/TR/2019/NOTE-charmod-norm-20190204/
最新公開バージョン:
https://www.w3.org/TR/charmod-norm/
最新編集者草案:
https://w3c.github.io/charmod-norm/
バグ追跡システム:
File a bug (open bugs)
旧バージョン:
https://www.w3.org/TR/2018/WD-charmod-norm-20180420/
編集者:
Addison Phillips (Amazon.com)
Github:
repository

要約

このドキュメントは、ウェブの文字モデル1.0: 基礎(Character Model for the World Wide Web 1.0: Fundamentals )[CHARMOD]に基づき、仕様書の作成者、ソフトウェア開発者、コンテンツ開発者にウェブ上の文字列の同一性マッチングに関する共通参照事項を提供し、それによって相互運用性を高めるためのものです。

このドキュメントのステータス

この項は、このドキュメントの公開時のステータスについて記述しています。他のドキュメントがこのドキュメントに取って代わることがありえます。現行のW3Cの刊行物およびこの技術報告の最新の改訂版のリストは、http://www.w3.org/TR/のW3C技術報告インデックスにあります。

このドキュメントのこの版は、以前の版からの大きな変更を表します。内容の大部分が変更され、勧告事項が大幅に変更されました。この事実は、ドキュメントの名前が「文字モデル: 正規化」から変更されたことに反映されています。

このドキュメントに関するコメントの送信

このドキュメントに関してコメントを行いたい場合は、githubの課題として提起してください。ドキュメントをレビューする際には、最新の編集者の版を参照してください。githubで課題を提起できない場合にのみ、電子メールでコメントを送ってください(下記リンクを参照)。あらゆるコメントを歓迎します。

コメントを追跡しやすくするために、コメントごとに個別に課題や電子メールを提起し、コメントを行う項をURLで指定してください。

このドキュメントは、国際化ワーキンググループによってワーキンググループ・ノートとして発表されました。

本ドキュメントに関するコメントを歓迎します。コメントはwww-international@w3.org(アーカイブ)にお送りください。

ワーキンググループ・ノートとしての公開は、W3Cメンバーによる承認を意味するものではありません。これは草案ドキュメントであるため、他のドキュメントによって、随時更新されたり、置き換えられたり、廃止されることもありえます。このドキュメントを「作業中」以外のものとして引用することは適当ではありません。

このドキュメントは、W3C特許方針の下で活動しているグループによって作成されました。

このドキュメントは、2018年2月1日のW3Cプロセス・ドキュメントによって管理されています。

1. はじめに

1.1 目標と範囲

ウェブの文字モデル(Character Model for the World Wide Web)の目標は、W3Cのユニバーサル・アクセスの目標に従い、言語、文字、表記体系や文化的な慣習に関わらず、すべての人がウェブを利用しやすくすることです。この目標を達成するための基本的な前提条件の1つは、世界中で用いられている文字を、明確に定義され、明確に理解される方法で送信し処理できるようにすることです。

このドキュメントは、ウェブの文字モデル: 基礎(Character Model for the World Wide Web: Fundamentals)[CHARMOD]の上に構築されています。本ドキュメントを正しく理解し適用できるようにするためには、このドキュメントの概念を理解することが重要です。

ウェブの文字モデル(Character Model for the World Wide Web)のこの部編では、文字列のマッチング—仕様や実装により、2つの文字列の値が同じなのか異なるのかを定義するプロセス—について説明します。このドキュメントでは、意味的に同等なテキストを別々にエンコードできる方法と、これが形式言語(ウェブを構成するフォーマットとプロトコルで用いられるものなど)にとって重要なマッチング操作に与える影響について説明します。

この仕様が対象とする主な読者は、W3C仕様の開発者です。この仕様とその部分は、他のW3C仕様から参照でき、他の仕様と同様にW3C仕様に対する適合基準を定義しています。

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

この仕様で説明している文字モデルは、仕様の作成者、ソフトウェア開発者、コンテンツ開発者に、一貫性があり相互運用可能なウェブ上のテキスト操作の共通参照事項を提供します。これら3つのグループが協力することにより、グローバルにアクセス可能なウェブを構築できます。

1.2 このドキュメントの構成

このドキュメントでは、ドキュメントのフォーマットにおける文字列の同一性マッチングに関する規則とプロセスを定義することにより、この問題に関するウェブの基本構成要素の1つを定義します。これらの規則は、個々の一貫性がある処理を保証するためにドキュメント・フォーマットで用いる識別子と構造マークアップ(構文コンテンツ)のために設計されており、仕様の作成者を対象としています。この項は、実装者を対象としています。

このドキュメントは大きく2つの部分に分かれています。

最初の部分では、文字列のマッチングに関する問題(この問題に関するUnicodeと大文字・小文字畳み込み(case folding)の影響など)について説明し、さまざまな課題や、これらの課題に対処するために用いられうる正規化メカニズムについて概説します。

2番目の部分では、W3C仕様で定義されている多くのドキュメントのフォーマットなどの形式言語で用いるための文字列の同一性マッチングの要件と勧告について説明します。これは主に、ウェブを機能的にし、ドキュメントの作成者に一貫性がある結果を提供することに関わります。

1.3 背景

この項では、この仕様で扱っているトピックに関する過去の背景について説明します。

文字モデルの中心となっているのは、Unicode標準[Unicode]とISO/IEC 10646[ISO10646]が共同で定義しているUCS(Universal Character Set)です。このドキュメントでは、UnicodeをUCSの同義語として用いています。文字モデルが成功すれば、世界中のウェブ・ユーザが、世界中の表記体系、文字、そして言語で(そして異なるプラットフォームで)書かれたウェブ・ドキュメントを交換し、読み、検索することが可能になります。

有用な背景情報がUnicode標準[Unicode]の冒頭の数章において提供されています。

この仕様の重要な部分の開発を示す要件に関する情報については、文字列の同一性マッチングおよび文字列のインデキシングの要件[CHARREQ]を参照してください。

1.4 用語と表記法

この項では、このドキュメント固有の用語と表記法について記載しています。

ウェブは、テキスト・ベースのフォーマットとプロトコルに基づいています。要件や詳細が極めて多様であるため、文字列のマッチングや検索を効果的に記述するためには、特定のフォーマットやプロトコルのさまざまな種類のテキストについて述べることができる用語を確立する必要があります。

Unicodeコードポイント(Unicode code point)(または「コードポイント」)は、個々のUnicode文字に割り当てられている数値を表します。Unicodeコードポイントは、0から0x10FFFF16の範囲です。(文字エンコーディングの用語に関するより深い議論は[CHARMOD]の4.1項を参照。)

Unicodeコードポイントは、U+hhhhで表され、このとき、hhhhは、最小で4桁、最大で6桁の16進数のシーケンスです。例えば、[U+20AC EURO SIGN]という文字のコードポイントはU+20ACです。

このドキュメントの例で用いている一部の文字は、特定のデバイスやディスプレイでは意図したとおりに表示されないかもしれません。これは通常、文字固有のフォントがローカルにインストールされていないことや、その他の特定の表示システム上の制限が原因です。このドキュメントでは、非ラテン文字の多くにウェブ・フォント(Webfont)を用いてフォールバックのグリフを提供していますが、デバイスがこのフォントの表示をサポートしていない可能性があります。編集者は、可能な限り、例が理解可能であることを確保するように努めました。

レガシー文字エンコーディング(legacy character encoding)は、Unicode文字集合内のすべての文字を対象としてエンコードしない文字エンコード形式です。

トランスコーダ(transcoder)は、2つの文字エンコーディング間でテキスト変換を行うプロセスです。このドキュメントでは最も一般的に、レガシー文字エンコーディングからUTF-8などのUnicodeエンコーディング形式に変換するプロセスを指します。

構文コンテンツ(syntactic content)は、フォーマットやプロトコルの構造に属する、ドキュメントのフォーマットやプロトコル内のテキストです。この定義には、通常「マークアップ」と見なされている値が含まれますが、HTTPヘッダーのフィールド名など、その他の値が含まれる可能性もあります。構文コンテンツは、フォーマットやプロトコルの構造を形成する文字ですべて構成されます。例えば、<>(これらに囲まれる要素名や、さまざまな属性も)は、HTMLドキュメントの構文コンテンツの一部です。

構文コンテンツは通常、1つまたは複数の仕様で定義され、特定のプロトコルやフォーマットに対する定義済みの予約語と、(ドキュメントのコンテンツではなく)ドキュメントの構造を形成するためにドキュメントの作成者が定義する文字列トークンおよび識別子の両方を含んでいます。

自然言語コンテンツ(natural language content)とは、ドキュメントの言語を含んでいるコンテンツのことであり、ドキュメント構造の一部を形成する、囲み構文コンテンツや組み込み構文コンテンツではありません。これは、ドキュメントの実際の「コンテンツ」または特定のプロトコルの「メッセージ」と考えることができます。[HTML]のimg要素にその画像に関する記述を含んでいるalt属性がある場合など、構文コンテンツには自然言語コンテンツを含むことができます。

資源(resource)は、このドキュメントの文脈では、自然言語コンテンツと、それを囲んでいるまたは含んでいる識別子などの構文コンテンツの両方を含む、特定のドキュメント、ファイル、またはプロトコルの「メッセージ」です。例えば、CSSとJavaScriptが組み込まれている少数のscript(スクリプト)のタグが含まれているHTMLドキュメントでは、ファイルと見なされているHTMLドキュメント全体が資源です。この用語は[RFC3986]で用いられている「資源」という用語と意図的に類似していますが、ここでは大まかに適用されています。

ユーザ指定の値(user-supplied value)は、特定のフォーマットやプロトコルの予約語とは異なり、ユーザによって割り当てられる語彙(vocabulary)内の予約されていない構文コンテンツです。例えば、CSSクラス名はCSSスタイルシートの構文の一部です。これは予約語ではなく、CSS仕様で事前に定義されているにもかかわらず、CSSの構文規則に従います。ユーザは一般的に、自分が定義するキーワードは、その規則の制限に従い、特定の自然言語の単語や概念を表すことができると考えます。

語彙(vocabulary)は、予約名のリストに加え、ユーザ指定の値(識別子など)をフォーマットやプロトコルで割り当てる方法を制御する一連の規則と仕様を提供します。これには、異なる場所に現れうる文字の範囲、順序、種類に対する制限が含まれることがあります。例えば、HTMLは、その要素と属性の名前に加え、列挙型の属性値を定義し、これにより、HTMLの構文コンテンツの「語彙」が定義されます。別の例としては、ECMAScriptがあり、これは、先頭または本文に表示できる識別子や変数名の文字の範囲を制限します。これは、文字列リテラルの値に対するものなど、場合によって異なる規則を適用します。

書記素(grapheme)は、一般的なユーザが一つの単位(文字)として認識する、テキストの視覚表現における1つ以上の文字のシーケンスです。書記素は、ソートやテキスト選択など、多くのテキスト操作に重要であるため、ユーザが認識する個々の文字間の境界を算出できる必要があります。Unicodeは、Unicode標準附属書#29: テキスト分割(Unicode Standard Annex #29: Text Segmentation)[UAX29]で書記素を算出するためのデフォルトのメカニズムを定義しており、この近似値を書記素クラスタ(grapheme cluster)と呼びます。定義済みのデフォルト書記素クラスタは2種類あります。特に明記していなければ、このドキュメントにおける書記素クラスタは、拡張デフォルト書記素クラスタを指します。(書記素クラスタに関する議論は、Unicode標準の2項[Unicode]にもあります。Unicode標準8.0版の2.11項の末尾近くを参照してください。)

自然言語ごとにニーズが異なるため、書記素クラスタに調整(tailoring)が必要な場合もあります。例えば、スロバキアのユーザは、「ch」という対のデフォルト書記素クラスタを一つの書記素クラスタとして扱いたいと考えるかもしれません。文字列コンテンツの言語とエンドユーザのプレファレンスとの間の相互作用は複雑になりえることに注意してください。

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行目の文に組み込まれている&#x2019;というHTMLエンティティーは、構文コンテンツの一部です。)
  • 自然言語コンテンツは、背景が灰色の太字の青いフォントで示されています。構文ではないコンテンツに加えて、7行目のaltの値(William Shakespeare)に自然言語のテキストが含まれています。
  • ユーザ指定の値はイタリック体で示しています。このケースでは、7行目にユーザ指定の値が3つあり、それらはimgタグのsrcaltid属性の値です。さらに、1行目のlang属性と3行目のcharset属性の値はユーザ指定の値です。
  • 語彙赤い下線で示しています。HTMLドキュメントの語彙は、[HTML5]で定義されている要素と属性(および、上記の例の属性dirの値ltrなどの一部の属性値)です。

上記のすべてのテキスト(テキスト・ファイル内のすべてのテキスト)で資源が構成されます。特定の資源に自然言語コンテンツがまったく含まれない可能性もあります(オレンジ色の長方形になるようにスタイル設定された4つの空のdiv要素で構成されるHTMLドキュメントを考えてみてください)。また、資源に構文コンテンツを含ま、自然言語コンテンツのみで構成することもできます。例えば、Hamletの独白を含んだプレーン・テキストのファイルなどです。この資源では、自然言語コンテンツに&#x2019;というHTMLエンティティーが含まれていますが、これが自然言語コンテンツと構文コンテンツの両方に属していることにも注意してください。

1.5 適合性

非規範的と記している項と同じく、この仕様のすべての作成ガイドライン、図、例、注は非規範的です。この仕様のその他の部分はすべて規範的です。

「することができる/してもよい(MAY)」、「しなければならない(MUST)」、「してはならない(MUST NOT)」、「推奨される(RECOMMENDED)」、「すべきである/する必要がある(SHOULD)」、「すべきでない/する必要がない(SHOULD NOT)」というキーワードは、[RFC2119]で記述されているように解釈されるべきです。

このドキュメントは、他の仕様の作成者のためのベスト・プラクティスに加え、実装とコンテンツの作成者に対する勧告を記述しています。このベスト・プラクティスは、国際化ワーキンググループの仕様開発者向け国際化ベスト・プラクティス[INTERNATIONAL-SPECS]にもあり、これは、W3C仕様のすべての国際化のベスト・プラクティスに対する一般的な参考資料として機能することを目的としています。

このドキュメントにベスト・プラクティスや勧告を記載する場合は、この段落のようなスタイルにしています。仕様と仕様の作成者に対する勧告の前には[S]が付きます。実装やソフトウェア開発者に対する勧告の前には[I]が付きます。コンテンツやコンテンツの作成者に対する勧告の前には[C]が付きます。

このドキュメントのベスト・プラクティスでは、特定の勧告に関する国際化ワーキンググループの意図を明確にするために[RFC2119]のキーワードを用いています。このドキュメントの勧告に従うことで、W3Cの「広範なレビュー」のプロセス中、実装中、作成者によるコンテンツ作成中の課題を回避できます。このドキュメント自体は、規範的なものではなく、随時改訂される可能性があります。

次の場合、仕様はこのドキュメントに適合していると主張できます。

  1. 命令文がMUSTであるかMUST NOTである、[S]が先行する適合基準に違反しない場合
  2. 命令文がSHOULDSHOULD NOT、またはRECOMMENDEDである、基準に従わない理由をドキュメント化している場合
  3. このドキュメントへの準拠を実装の適合性要件にしている場合
  4. このドキュメントへの準拠をコンテンツの適合性要件にしている場合

仕様に課される要件によって、その仕様に準拠していると主張する実装やコンテンツに要件が間接的に課される可能性があります。

手続きに関する記述がこの仕様に含まれていれば、それは望ましい外部の挙動を規定する方法であると理解すべきです。目に見える挙動に影響がない限り、別の手段を実装に用いて同じ結果を達成できます(MAY)。

2. 文字列マッチングの問題

ウェブは主に、文字データに基づくドキュメントのフォーマットとプロトコルで構成されています。このフォーマットやプロトコルは、主に何らかの形式の構造マークアップまたは構文コンテンツを含むテキスト・ファイルで構成される資源の集合と見なすことができます。このような構文コンテンツやドキュメントのデータを処理するためには、マッチング(正規表現を含む)、インデキシング、検索、ソートなどの、文字列ベースの操作が必要です。

ユーザ(特に実装者)は、同じような文字列のマッチングまたは不マッチング、または彼らがテキストに適用する可能性のあるさまざまな変換の有効性に関して(特に構文コンテンツに対してですが、ウェブ上の多くの種類のテキスト処理も含まれる)、単純な期待を抱くことがあります。

ウェブは基本的に、ドキュメント内のテキストの表現方法の違いに敏感であるため、同じテキストを表現するさまざまな方法を考慮に入れないと、ユーザが混乱したり、予期しない結果を招いたりする可能性があります。このドキュメントでは、以下の項で、ウェブのテキストに対するユーザの認識とウェブが依存する文字列処理の両方に影響を与えるさまざまな種類のテキストのバリエーションについて説明します。

2.1 大文字・小文字のマッピングと畳み込み

一部の文字と表記体系では、大文字、小文字、および先頭文字大文字を区別します。インドのブラーフミー系文字、アラビア文字、および中国語、日本語、韓国語の記述に用いられる文字を含むほとんどの文字には、大文字・小文字の区別はありませんが、一部の重要な文字にはあります。このような文字の例には、このドキュメントの大部分で用いているラテン文字に加え、ギリシア文字、アルメニア文字、キリル文字などがあります。

大文字・小文字マッピング(case mapping)は、文字を大文字、小文字、先頭文字大文字などの特定の文字に変換するプロセスです。大文字・小文字の区別がある文字に対し、Unicodeでは、各Unicodeコードポイントに対してデフォルトの大文字、小文字、および先頭文字大文字の文字マッピングを定義しています。大文字・小文字マッピングは、一見したところでは単純に見えます。しかし、さまざまな言語でUnicodeの全範囲を扱うときに考慮する必要があるバリエーションが存在しています。

大文字・小文字畳み込み(case folding)は、比較の目的で、大文字・小文字が異なるだけの2つのテキストを同じとするプロセスです。つまり、文字列のマッチングを目的としています。これは、主に表示を目的としている大文字・小文字マッピングとは異なります。デフォルトの大文字・小文字マッピングと同じように、Unicodeでは、各Unicodeコードポイントに対してデフォルトの大文字・小文字畳み込みマッピング(「case folding」)を定義しています。Unicodeは、2つの形式の大文字・小文字畳み込みを定義しており、これについては後で検討します。

大文字・小文字マッピングと同様に、ほとんどの文字には大文字・小文字の区別がないため、ほとんどのUnicodeコードポイントでは大文字・小文字畳み込みは必要ありません。大文字・小文字畳み込みがあるコードポイントの場合、その大部分には、別の1つのマッチする(通常は小文字)コードポイントへの単純で直接的なマッピングが存在しています。Unicodeでは、Unicodeで定義されている両方の大文字・小文字畳み込みに畳み込みの集合が含まれているため、その集合を共通(common)と呼びます。

1つのUnicodeコードポイントから2つ以上のコードポイントにマッピングされている大文字・小文字畳み込みを持つ文字も少数存在しています。この大文字・小文字畳み込みの集合を完全な(full)大文字・小文字畳み込みと呼びます。完全な(full)大文字・小文字畳み込みと共通の(common)大文字・小文字畳み込みを一緒に用いて、すべてのUnicodeに対するデフォルトの大文字・小文字畳み込みを提供します。このドキュメントでは、この形式の大文字・小文字畳み込みを、完全な大文字・小文字畳み込み(full casefolding)またはUnicode完全(Unicode full)と呼びます。

大文字・小文字畳み込みの操作を実行する際に追加の格納領域を割り当てられないアプリケーションもあるため、Unicodeは、通常はより多くのまたはより少ないコードポイントに畳み込みを行うコードポイントをマッピングする代わりに、比較の目的で1つのコードポイントを用いるシンプルな(simple)大文字・小文字畳み込みを提供しています。完全な畳み込みとは異なり、この畳み込みによりテキストのコンテンツ(そして、潜在的に意味)は常に変わります。完全な大文字・小文字畳み込みと同様に、シンプルな大文字・小文字畳み込み(simple casefolding)またはUnicodeシンプル(Unicode simple)の大文字・小文字畳み込みは、Unicodeの全範囲を網羅するように、シンプルなsimpleマッピングと共通の(common)マッピングとを組み合わせたものです。Unicodeシンプルは、ウェブでの使用には適していません。

大文字・小文字畳み込みでは、後で復元できない形で文字列から情報が削除されることに注意してください。例えば、ドイツ語の2つのsの文字は、必ずしも畳み込まれたテキストのßを表すわけではありません。

2.1.1 言語依存性

大文字・小文字マッピングと大文字・小文字畳み込みのもう1つの側面は、言語依存でありえることです。Unicodeでは、エンコードされている文字ごとにデフォルトの大文字・小文字マッピングと大文字・小文字畳み込みを定義していますが、これらはデフォルトにすぎず、すべての場合に適しているわけではありません。言語によっては、特定の言語のニーズに合わせて大文字・小文字マッピングを調整する必要があります。その一例は、ラテン文字で書かれたチュルク語族です。

上記の例(および、このドキュメント全般)では、マッチングを目的とした大文字・小文字畳み込みに焦点を当てていますが、大文字・小文字マッピングも言語固有であることに注意してください。トルコで2番目に大きい都市の名前は「Diyarbakır」(ディヤルバクル)で、ドットありとドットなしの文字iが両方とも含まれています。

2.1.2 大文字・小文字畳み込みの用途

ドキュメントのフォーマットやプロトコルには、定義している語彙や、フォーマットやプロトコルで認められているユーザ指定の値の大文字・小文字の違いを無視して、相互運用性を促進しようとしたり、コンテンツの作成者に支援を提供したりするものもあります。

セマンティック上は重要でなかったり、完全にはユーザの管理下にない形で大文字・小文字が異なる場合があります。これは、ドキュメントを検索するときに特に当てはまりますが、識別子などの、ユーザやコンテンツにより生成された値のマッチング・ルールを定義するときにも適用されることがあります。このような状況では、大文字・小文字を区別しないマッチングが望ましいかもしれません。

語彙を定義する際に考慮すべき重要な点の1つは、値がUnicodeのASCII[ASCII]サブセットに制限されているかどうか、または潜在的により複雑な大文字・小文字畳み込みの要件を持っている文字(ラテン文字のアクセント記号や非ラテン文字を含む広範囲なUnicodeなど)の使用が語彙で認められているかどうかです。これらのさまざまな要件に対処するために、このドキュメントでは、ドキュメントのフォーマットやプロトコルにおける文字列の同一性マッチングの目的に対応した4種類の大文字・小文字畳み込みマッチングを定義しています。

大文字・小文字を区別するマッチング(case sensitive matching): コードポイントは、大文字・小文字畳み込みなしに直接比較されます。

ASCIIの大文字・小文字を区別しないマッチング(ASCII case-insensitive matching)は、0x41から0x5A(AからZ)の範囲のすべてのASCIIコードポイントが、対応する0x61から0x7A(aからz)のコードポイントにマッピングされているかのようにコードポイントのシーケンスを比較します。語彙自体がASCIIに制約されている場合は、大文字・小文字を区別しないASCIIマッチングが要求される可能性があります。

Unicodeの大文字・小文字を区別しないマッチング(Unicode case-insensitive matching)は、Unicode完全の大文字・小文字畳み込み(上記参照)が入力シーケンスのどちらにも適用されているかのようにコードポイントのシーケンスを比較します。

言語依存の大文字・小文字を区別するマッチング(language-sensitive case-sensitive matching)は、ドキュメントのフォーマットやプロトコルに構文コンテンツの言語に関する情報が含まれている場合や、言語依存の大文字・小文字畳み込みが区別されて適用されている場合といった、まれなケースに有用です。これらの大文字・小文字畳み込みは、Unicodeコンソーシアムの共通ロケール・データ・リポジトリ(Common Locale Data Repository)[UAX35]プロジェクトで定義されています。

大文字・小文字畳み込みを処理する方法に関するアドバイスについては、§ 3.1.6 大文字・小文字畳み込みに関する追加の留意点を参照してください。

2.2 Unicodeの正規化

Unicodeテキストでは、さまざまな種類のバリエーションが発生します。同じ抽象文字を表すために、いくつかの異なるUnicodeコードポイントのシーケンスを使用できる場合があります。コードポイントを比較してテキストの検索またはマッチングを行う場合、これらのエンコーディングのバリエーションにより、テキストの値はユーザが同じであると予想するものとマッチしません。

アプリケーションは、異なるコードポイントのシーケンスを用いているテキストにおいて意味の同等性を見つける必要があるため、Unicodeは、意味が同等な2つのテキストが同一であるとするUnicodeの正規形(Unicode Normalization Forms)[UAX15]という方法を定義しています。

ウェブに関する仕様や実装では、テキストのUnicode正規化は必要ではなく、構文コンテンツと自然言語コンテンツを後で処理するときに用いられる文字列のマッチング・アルゴリズムも考慮しないため、資源がこれらのバリエーションの影響を受けることはしばしばあります。そのため、コンテンツの開発者は、後の問題を回避するために、確実に一貫性がある表現を提供する必要があります。

しかし、通常、テキストとして表示されたときには見た目の違いがないため、特定の資源や資源の集合に一貫性があるテキスト表現が用いられていることをユーザが確信するのは困難でありえます。したがって、ツールや実装では、(ユーザの頭の中で)マッチする「はず」の視覚的または論理的に同等な文字列が異なる値であると考えられるときにユーザが経験する困難を考慮する必要があります。ユーザがこれらの違いを確認したり、必要に応じてそれらを正規化したりするための手段を提供することで、エンドユーザが情報源のドキュメントに含まれる目に見えない違いから生じる失敗を回避できるようになります。例えば、W3Cの検証ソフトは、HTMLドキュメントが完全なUnicode正規形Cになっていない場合に警告を出します。

2.2.1 正規同等と互換同等

Unicodeは、正規同等互換同等という2種類の文字間の同等性を定義しています。

正規同等(canonical equivalence)は、同じ抽象文字を表すUnicodeコードポイント間またはUnicodeコードポイントのシーケンス間の基本的な同等性です。正規同等のシーケンスは、理想的には見た目が同じであるべきで(それらが、多少異なって見える原因となる要因は多くありますが)、それらはあたかも同じであるかのように扱われ処理されるべきです。Unicodeは、2つの異なるエンコードでありながらも正規同等であるテキスト間の主な違いを取り除く、正規分解(canonical decomposition)と呼ばれるプロセスを定義しています。

Unicodeで定義されている正規同等の例には次のようなものがあります。

  • Ç 合成済シーケンスと合成可能シーケンス。一部の文字は、基本文字とそれに続く1つ以上の合成可能文字で構成することができます。同じ文字が、異なる「合成済」文字としてエンコードされていることもあります。この例では、文字Ç[U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA]は、基底文字C[U+0043 LATIN CAPITAL LETTER C]で始まり、その後に◌̧[U+0327 COMBINING CEDILLA]が続く文字シーケンスと正規同等です。このような同等性は、複数の合成可能記号を持つ文字にまで広げることができます。
  • q̣̇ 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]は、合成可能記号の順序が異なっていても同等です。慎重にこの例を選択していることに注意してください。上ドットの文字と下ドットの文字は、基底文字の反対「側」にあります。同じ側でダイアクリティカル・マークを合成させる順番は、位置に意味がある場合が多くあります(ただし、順序が表示には関係ない場合もあります)。
  • Ω シングルトン・マッピング。これらは、レガシー文字エンコーディングをサポートするために、他の点では同等な文字を別々にエンコードする必要があるためのものです。この例では、オーム記号[U+2126 OHM SYMBOL]は、ギリシア文字のオメガΩ[U+03A9 GREEK CAPITAL LETTER OMEGA]と正規同等(そして、見た目が同じ)です。(シングルトンのもう1つの例は、上記のエンコードのバリエーションの例[U+212B ANGSTROM SIGN]です。)
  • 가 ハングル。ハングル文字は、朝鮮語を記述するために用いられます。この文字は論理的に構成されており、各音節は子音と母音を表す特定の部分から形成されるほぼ正方形の書記素です。字母と呼ばれるこれらの特定の部分は、Unicodeでエンコードされています。また、構成された音節も同様です。したがって、音節[U+AC00 [Hangul Syllable, First]]は、その構成要素である字母文字[U+1100 HANGUL CHOSEONG KIYEOK] [U+1161 HANGUL JUNGSEONG A]と正規同等です。

互換同等(compatibility equivalence)は、同じ抽象文字を表すUnicode文字またはUnicode文字のシーケンス間の同等性が弱く、見た目や動作が異なる場合があります。一般的に、互換分解(compatibility decomposition)と呼ばれるプロセスで、上付き文字、下付き文字、回転、丸などのフォーマットのバリエーションが削除されますが、他のバリエーションも存在しています。多くの場合、互換分解がある文字は意味的な性質の違いを表します。したがって、互換分解を持つ異なる文字を置き換えて用いると、テキストの意味が変わる可能性があります。互換分解後に同等であるテキストは、事前に同じであると認識されていないことが多く、形式言語では同等として扱うべきではありません(SHOULD NOT)。

上記の表では、示されている文字は実際のUnicodeコードポイントであり、単なるコンテキストやスタイルに起因する表示上のバリエーションではないことに注意することが重要です。各文字は、さまざまなレガシー文字エンコーディングとの互換性のためにUnicodeでエンコードされています。これらは、これらの非互換の文字で用いられる通常の種類の表示処理と混同すべきではありません。

例えば、ほとんどのアラビア文字のテキストは、Unicodeのアラビア文字ブロック(U+0600から始まる)の文字を用います。テキストの表示に用いられる実際のグリフは、「字形変更」(shaping)と呼ばれるプロセスにおいて、単語内の位置(語頭、語中、語末、または独立)に基づき、フォントとテキストの処理ロジックを用いて選ばれます。上記の表では、アラビア文字ه[U+0647 ARABIC LETTER HEH]の4つの表示形を示しています。表示される文字はU+FE00ブロックの互換文字で、それぞれが特定の「位置」の形を表しており、表示されている4つのコードポイントは、それぞれ通常のアラビア文字ه[U+0647 ARABIC LETTER HEH]に対する互換分解を持っています。これらの表示形は、同等の表示形を含むレガシー文字エンコーディングとのラウンド・トリップ(round-trip)のエンコーディング変換のサポートのみを目的としています。それ以外の場合、「heh」という文字シーケンスを含んでいる文字列は、単に一連のU+0647のコードポイントとしてエンコードされ、表示システムとフォントが適切な形を提供します。

同様に、半角形および全角形と回転文字(縦書きテキストで使用)のバリエーションは、主にレガシー文字エンコーディングとの互換性のために、別々のコードポイントとしてエンコードされています。多くの場合、これらのバリエーションは東アジアの幅(East Asian Width)[UAX11]で説明しているUnicodeプロパティーに関連しています。縦書きテキスト表示形の議論ついては、Unicode縦書きテキスト・レイアウト(Unicode Vertical Text Layout)[UTR50] も参照してください。

上記で示したような、互換分解を持つ文字の場合、K Unicode正規形は、テキストを「通常の」または「予期される」Unicodeコードポイントに変換します。しかし、これらの互換文字の存在は、通常のテキストのレイアウトと表示の過程で生成される見た目が似ているバリエーションがUnicode正規化の影響を受けているということを意味すると考えることはできません。違うのです。

2.2.2 合成と分解

次に、これらのUnicodeが定義する2種類の同等性は、別の対のバリエーションである「分解」と「合成」によってグループ分けされます。「分解」では、視覚文字の分離可能な論理部分は、基底文字と合成可能記号のシーケンスに分割され、結果として得られるコードポイントは固定的な正規の順序になります。「合成」では、分解を実行した後に、特定の規則に従って合成可能記号が基底文字と再合成されます。

警告

大ざっぱに言うと、NFCでは、個々の合成可能文字のシーケンス(基底文字の後に1つ以上の合成可能文字が続く)が、可能な限り、正規同等の合成済文字に置き換えられるように定義されています。

これが意味しないことに気づくことはかなり重要です。すべての文字シーケンスに合成済同等があるとは限らないため、結果として得られる文字シーケンスには、それでも合成可能記号を含めることができます。実際のところ、これまで見たように、この例のデーヴァナーガリーの母音のように、多くの文字では合成可能記号の使用に代わるものは提供されていません。また、正規化規則によって組み合わせが阻止され、特定の基底文字と合成可能記号が合成済文字に置き換えられないというケースもあります。例えば、インド系文字には、マッチする合成済文字が存在していても、合成除外の規則により、特定のシーケンスの基底文字とダイアクリティカル・マークを合成しないものもあります。別の方法では合成される2つの文字の間に別の合成可能記号があることによって合成が妨げられる可能性もあります。

2.2.3 Unicode正規形

4つのUnicode正規形があります。各形式は、1文字のコードで名付けられています。

  • 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]という文字が含まれている)は、互換正規形の1つ(つまり、NFKDまたはNFKC)を用いて正規化すると、81/2というASCIIの文字シーケンスになります。

2.3 同じに見える文字と正規化の制限

多くのユーザは、特定のUnicode正規形が適用されているものを含め、同じに見える2つの文字列が実際には同じ基礎となるUnicodeコードポイントを用いていない可能性があることに驚きます。これには、より破壊性のあるNFKCNFKDの互換正規形が適用された文字列が含まれます。文字列、トークン、または識別子が視覚的に同じに見えても、それらは異なる方法でエンコードされている可能性があります。

Unicode正規正規形は、特定の抽象文字または書記素クラスタに使用できる複数の異なるコードポイントのシーケンスを畳み込んで同じコードポイントのシーケンスを用いることに関係しています。しかし、論理的に異なる文字または書記素クラスタは、依然として同じまたは非常に似ているように見える可能性があります。対の書記素が同じに見える(または非常によく似ている)場合、それらを同形異義(homograph)と呼びます。対の書記素が類似しているように見える、または同形異義であるけれども実際には論理的に異なる文字または文字シーケンスを表す場合、それらは混同しやすい(confusable)と言われます。

同じまたは同じに見える例は、1つの文字体系内にも現れる可能性があります。これは、「0」と「O」や「l」と「1」のような、似た文字の形をとる可能性があります。しかし、別の文字体系やさまざまな互換文字を用いると、区別が容易ではないバリエーションが表示される可能性があります。Unicode正規化によってこれらが結合される場合もありますが、そうでない場合も多くあります。

見た目が同じまたは混同しやすい文字は、なりすましやその他のセキュリティ上のリスクを引き起こす可能性があります。これは、1つの文字体系内でも、別々の文字体系内の類似する文字でも当てはまります。同形異義との混同の可能性に関するさらなる議論と例については、[UTS39]が参考になります。

同じまたは類似する文字に加えて、逆の問題もあります。Unicode正規化では、NFKCNFKDの互換形であったとしても、本質的な意味や機能は同じだけれども見た目や用法が異なる文字をまとめることはありません。例えば、U+002E(.)とU+3002(。)は、どちらも文末の句読点として機能しますが、これらの文字は別個の固有性を持っているため、正規化によって区別が削除されることはありません。

2.4 正規化と大文字・小文字畳み込みの相互作用

もう1つの複雑な問題は、大文字・小文字畳み込みまたは大文字・小文字マッピングが、大文字・小文字の操作が適用される文字列の正規化に影響を与える可能性があることです。2つの文字列を大文字・小文字を区別しないで比較することが目的である場合は、大文字・小文字畳み込み操作の結果を再正規化しなければならず、さもないと、結果として得られる大文字・小文字畳み込みが行われた文字列はマッチしない可能性があります。

Unicode正規正規形と大文字・小文字畳み込みは、一緒に用いると、閉じられます。文字列が大文字・小文字畳み込みされ、それにNFCやNFDが適用されれば、大文字・小文字畳み込みとUnicode正規形をさらに適用しても、異なる文字列にはなりません。

文字間の互換性のバリエーションを無視して文字列を比較する場合は、互換分解のステップにより、文字は大文字・小文字畳み込みを行ってから正規化する必要があるものになりえるため、追加の正規化レベルを適用する必要があります。

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

ほとんどのドキュメントのフォーマットやプロトコルは、他の方法では入力、処理、エンコードが困難な文字の組み込みを可能とするためのエスケープ法を提供しています。このエスケープ法は、特定の資源内で文字を表すのと同等の手段を追加提供します。これにより、ドキュメントで用いられている文字エンコード体系では表されないUnicode文字のエンコーディングも可能になります。

仕様におけるエスケープ法の定義のガイドラインを含む、文字エスケープの詳細については、[CHARMOD]の4.6項を参照してください。

文字のエスケープとインクルードの展開はコンテキスト、つまり、文字列マッチング操作が実行されるときに適用が検討される構文コンテンツやプログラミング言語に依存します。suconではなくsu&#xE7;onが含まれているXMLドキュメントで文字列suconを検索するとします。プレーン・テキストのエディタで検索が行われれば、コンテキストはプレーン・テキスト(構文コンテンツやプログラミング言語は適用されない)であり、&#xE7;という文字エスケープは認識されないため、展開されず、検索は失敗します。XMLブラウザで検索が実行されると、コンテキストはXMLであり、(XMLで定義されている)文字エスケープが展開され、検索は成功します。

これらの中間のケースは、展開されない実体参照を含むXMLドキュメントの表示を意図的に提供するXMLエディタです。このケースでは、その疑似XMLビューに対する検索は、意図的に実体を展開しません。その特定のコンテキストでは、実体参照はインクルードとは見なされず、展開される必要はありません。

例えば、 U+20AC EURO SIGNは、16進数の実体&#x20ac;や10進数の実体&#8364;としてHTMLでエンコードすることもできます。JavaScriptやJSONファイルでは、\u20ac\u{20AC}と表示される可能性がありますが、CSSスタイルシートでは\20acと表示できます。これらの表現はすべて同じリテラル文字値であるをエンコードします。

文字エスケープは通常、ドキュメントが処理されてフォーマットやプロトコル内の文字列のマッチングが行われる前に解釈されます。上記で用いた例に戻ります。

このテキストは次のように表示されるはずです。Hello world!

これが機能するためには、CSSとHTMLでそれぞれ異なるエスケープ法が用いられていても、ユーザ・エージェント(ブラウザ)は、helloというクラス名を表す2つの文字列をマッチさせなければなりませんでした。上記のフラグメントは、テキストは異なるものである可能性があるけれども、仕様に従って「同じ」と見なされる可能性がある方法の1つを示しています。h\e9lloというクラス名は、HTMLのマークアップであるクラス名h&#xe9;lloとマッチします(そして、e[U+00E9 LATIN SMALL LETTER E WITH ACUTE]というコードポイントを用いたリテラル値helloにもマッチするでしょう)。

形式言語やドキュメントのフォーマットは、ある資源のテキストを別の資源に含める機能を提供することがしばしばあります。インクルード(include)は、コンテンツを資源の本体に挿入する方法です。インクルード法は、処理時にコンテンツを資源にインポートします。これはドキュメントの構造に影響を与え、潜在的にドキュメントの語彙に対するマッチングに影響します。インクルードの例は、XMLの実体参照、XInclude[XInclude]仕様、およびCSSの@import規則です。

インクルードは、合成可能記号で(文字エスケープの形か、インクルードされた資源内の文字リテラルとしてのいずれかで)始まっていなければ、インクルード正規化(include normalized)されていると見なされます。

2.6 目に見えないUnicode文字

Unicodeは、ドキュメントの作成者がテキストの見た目やパフォーマンスを制御するのに役立つ特殊な目的の文字をいくつか提供しています。これらの文字の多くは目に見えないか、または同等のキーボードがないため、ユーザはその有無を常に意識しているわけではありません。その結果、これらの文字は、エンコードされている文字シーケンスの一部に含まれているけれども、予想されるマッチング・テキストには含まれていない場合には、文字列のマッチングを妨げる可能性があります。これらの文字の例は次のとおりです。

Unicode制御文字U+200D Zero Width Joiner(別名ZWJ)とU+200C Zero Width Non-Joiner(別名ZWNJ)。これらの文字は、合字の形成を制御する(望ましくない合字の形成を阻止するか、望ましい合字の形成を促すかのいずれか)ために使用できますが、その主な用途は、アラビア語やさまざまなインド文字などの複雑な文字の結合と字形選択の制御です。一部のインド語の文字では、特定の結合がとる字形を作成者が制御できるようにするために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)は、別の見た目やグリフを選択するために用いられる文字です(文字モデル: 基礎[CHARMOD]を参照)。例えば、白黒とカラーの絵文字を選択するために用いられます。これらは、定義済みの表意文字異体字シーケンス(ideographic variation sequence、IVS)でも用いられます。多くの例が、Unicode文字データベース(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は「BOM」(Byte Order Mark)として知られているため、これは、U+FEFFという文字の代わりとして機能します。BOMはプレーン・テキスト・ファイルがUnicode文字エンコーディングであることを示すために、ファイルの先頭で用います。

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

テキストの方向のあいまいさに対処するためにUnicodeが定義している方法の1つは、方向性の流れの開始と終了を示す目に見えない制御文字です。双方向制御は、テキストの見た目に影響を与える可能性がありますが(Unicode双方向アルゴリズムのテキストの表示に役立つため)、テキストが制御なしに自然に双方向の流れになった場合は、テキストに影響を与えない可能性があります。上記の文字のように、これらの制御は目に見えないため、マッチングに意図しない影響を与える可能性があります。

これらのほとんどすべてのケースにおいて、ユーザは、特定のドキュメントまたはテキストの文字列にこれらの文字のうちの1つが含まれていたり除かれていたりするかどうかを認識したり確信したりすることができないかもしれません。テキストのマッチングは、基礎となるコードポイントのマッチングに依存するため、これらの記号に起因するテキストのエンコーディングのバリエーションによって、(ユーザの観点からは)成功するはずのマッチングが、不思議なことに失敗する可能性があります。

2.7 絵文字シーケンス

Unicodeの新しい機能は、絵文字です。[UTR51]で、Unicodeはこれを次のように説明しています。

絵文字は、一般的にカラフルな漫画の形で表され、テキストのインラインで用いられる象形文字(絵の記号)です。これは、顔、天気、乗り物や建物、食べ物や飲み物、動物や植物、感情や活動を表すアイコンなどを表します。

絵文字は、U+200D ZERO WIDTH JOINER(別名ZWJ)などの、さまざまな絵文字修飾子を併用して、より複雑な絵文字を作成できます。

例えば、絵文字(👪[U+1F46A FAMILY])は、U+1F468 U+200D U+1F469 U+200D U+1F466というシーケンスで絵文字間にZWJを用いて形成することもできます。他の絵文字を変更または追加すると、家族の構成が変わる可能性があります。例えば、👨‍👩‍👧‍👧 U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F467というシーケンスは、この種の構成をサポートするシステム上で「家族:男性、女性、女の子、女の子」の合成済み絵文字になります。多くの一般的な絵文字は、ZWJシーケンスを用いてのみ形成できます。詳細については、[UTR51]を参照してください。

絵文字の後に絵文字修飾文字を続けることができます。この修飾子により、人を表す絵文字用の肌の色を選択できるようになります。これらの文字は通常、変更する対象の基底絵文字の後に置かれる見えない修飾子です。例えば、次のとおりです。👨 👨🏻 👨🏼 👨🏽 👨🏾 👨🏿

絵文字の後に異体字セレクタを置いて、基底絵文字のテキスト(白黒、U+FF0E Variation Selector 15で示す)やカラー(U+FF0F Variation Selector 16で示す)での表示を示すこともできます。

絵文字の使用におけるさらに別の新機軸は旗です。国旗は、ザンビアの国コード(ZM)である🇿 [U+1F1FF REGIONAL INDICATOR SYMBOL LETTER Z] 🇲 [U+1F1F2 REGIONAL INDICATOR SYMBOL LETTER M]というシーケンスなどの[BCP47]のレジストリから抽出した国コードで構成可能です。他の地域の旗や特別な目的の旗は、旗の絵文字を取消しタグ(cancel tag)で終わるさまざまな記号や地域指示コードと一緒に用いて構成できます。例えば、スコットランドの旗(🏴󠁧󠁢󠁳󠁣󠁴󠁿)は、次のように構成することができます。

これらの方法はそれぞれに組み合わせて使用できるため、非常に複雑な文字シーケンスで1つの絵文字書記素や画像を形成できます。非常に類似した絵文字シーケンスでも、まったく同じエンコードのシーケンスを用いていない場合があります。ほとんどの場合、上記の修飾子や組み合わせは、エンドユーザのキーボード(1つの絵「文字」として表示されている)によって生成されます。この多様なエンコーディングのオプションは、さまざまなベンダーが、Unicodeによって「置き換えが推奨」されているシーケンスのみを(かつ、厳密に)用いるという範囲で部分的に対処されています。これは、ユーザが期待するオプションをフォントとキーボードが提供する用意があることをベンダーが確認するのに役立ちます。それでも、ユーザは基本的なエンコーディングの複雑さに気付かないだろうし、生成方法は推奨されるものに限られるわけではありません。絵文字シーケンスは急速に進化しているため、近い将来、絵文字のマッチングを助けたり阻止したりする追加開発があるかもしれません。Unicode正規化は、これらのシーケンスを並べ替えたり、修飾子の挿入または削除を行ったりはしません。したがって、ユーザと実装者は、名前空間やその他のマッチングのコンテキストにおいて絵文字を用いるユーザが、エンコーディングのバリエーションにより、予期しない「文字」のミスマッチに遭遇する可能性があることに注意してください。

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

資源は、ウェブ上のドキュメントのフォーマットをシリアル化するために、レガシー文字エンコーディングを含むさまざまな文字エンコーディング・スキームを使用できます。個々の文字エンコーディング・スキームは、さまざまなバイト値とシーケンスを用いてUCSの特定のサブセットを表します。

すべてのドキュメント、フォーマット、プロトコルに、UTF-8などのUnicode文字エンコーディングを選択することが、強くお勧めする勧告です。これは、レガシー文字エンコーディングを用いることで得られる追加のユーティリティーはなく、この項の残りの部分の留意点は完全に避けられるだろうからです。

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

仕様では主に、個々のドキュメントを、ドキュメントの文字エンコーディング(レガシー文字エンコーディングまたはUTF-8などのUnicodeエンコーディング)から変換した後のUnicodeエスケープ文字列と見なし、その後、ドキュメントの処理に進む前に文字エスケープをアンエスケープすることで、結果として得られるバリエーションに対処します。

1つのレガシー文字エンコーディングであっても、実装にはさまざまなバリエーションがありえます。有名な例の1つは、Shift_JISというレガシーの日本語エンコーディングです。さまざまなトランスコーダの実装においては、特定のバイト・シーケンスをUnicodeにマッピングする方法の選択に直面しました。そのため、0x80.60というバイト・シーケンス(JIS X 0208文字集合の0x2141)は、U+301C WAVE DASHにマッピングされる実装もあれば、U+FF5E FULL WIDTH TILDEを選択する実装もありました。これは、合理的で自己矛盾のない2つのトランスコーダが、同じ入力から異なるUnicode文字シーケンスを生成する可能性があることを意味します。ある意味では、エンコーディング[Encoding]の仕様は、ウェブの実装が確実に相互運用可能な同じマッピングを使用できるようにするために存在しています。しかし、エンコーディングの仕様に準拠しているトランスコーダが、ウェブ上で見つかったドキュメントに適用されたり、特定のドキュメントのフォーマットやプロトコルで表示されるデータを処理するために用いられる保証はありません。

Unicodeへの変換に関するもう1つの留意点は、視覚的な格納順序を用いる双方向文字(ヘブライ語やアラビア語など)のレガシー文字エンコーディングの存在です。つまり、Unicodeやその他の現代のエンコーディングとは異なり、その文字は、画面表示される順序で左から右に(ライン・プリンタの場合のように)メモリに格納されます。これらのエンコードをUnicodeに変換したり、これらのエンコーディング内のテキストを比較したりするときに、元のテキストと対象テキストの両方を論理的な順序に配置するように注意しなければなりません。詳細については、[CHARMOD]の3.3.1項を参照してください。

2.9 その他の種類の同等性

自然言語検索や「検索」機能を実行するときに適しているその他の種類の同等性や処理があります。これについては、文字モデル・シリーズのドキュメントの別の部編([STRING-SEARCH])で説明しています。語彙の仕様や、形式構文用のマッチング・アルゴリズムを定義している仕様においては、そのドキュメントに記述されている独自の畳み込み、マッピング、または処理を追加適用しようとする試みは、一貫性がある予測可能な結果の生成を妨げるため、避けるべきです(SHOULD)。

3. ドキュメントのフォーマットとプロトコルにおける構文コンテンツの文字列マッチング

文字列にさまざまな文字エンコーディングを使用でき、そのエンコーディング内でさまざまな文字シーケンスを使用でき、このドキュメントで説明しているその他のバリエーション(大文字・小文字など)があるウェブ環境において文字列の同一性を評価する一貫性があるプロセスを確立することが重要です。

この章では、構文コンテンツにおいて文字列マッチングを規定し実装するための要件を定義します。

3.1 マッチング・アルゴリズムの選択

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

問題となっているフォーマットやプロトコルに関するユーザにとっての利点が実装のコストと複雑さを上回る場合、仕様は大文字・小文字を区別しないことを選択できます。大文字・小文字畳み込みと正規化はどちらも、表示や、場合によってはテキストの意味などを含む、比較する値に影響を与える可能性があるため、また、この操作は比較的高価であるため、大文字・小文字を区別しないという選択は一般的にお勧めできません。

大文字・小文字を区別しない特別なケースは、ASCII/基本ラテンの範囲(つまり、U+0000からU+007Fのコードポイント)に限定されている語彙です。その仕様では、その文字の範囲でのみ大文字・小文字を区別しないことを選択できます。これにより、マッチングの実装が非常にシンプルになります。しかし、この形のマッチングは、ユーザがマッチングの挙動を理解するのが難しく、ASCII以外の文字や言語を用いているユーザにとって不便であるため、識別子や構文に広い範囲のUnicodeを認めている仕様には適していません。つまり、greenGREENにマッチするけれども、grüßGRÜẞや、おそらくGRÜSSにはマッチしない(しかし、GRüßにはマッチする)場合、ユーザは、奇妙で予測不可能だと感じます。

3.1.1 マッチング・アルゴリズム

マッチング・アルゴリズムでは、2つの文字列を比較するために必要な一連のステップを説明します。

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

3.1.2 適切な正規化ステップを実行する

特定の仕様に対するテキストの正しい正規化は、フォーマットやプロトコルの語彙の要件によって異なります。テキストの正規化には4つの選択肢があります。

  1. デフォルト(default)。この正規化手順はテキストには影響を及ぼさず、結果として、大文字・小文字とUnicode正規形の違いの両方を区別します。これは推奨される(RECOMMENDED)正規化ステップです。
  2. ASCII大文字・小文字畳み込み(ASCII case fold)。テキストとASCII(基本ラテン、U+0000からU+007F)の範囲の大文字・小文字畳み込みの文字との比較。Unicode正規形は適用されません。このステップは、ASCIIの範囲に制限されている(または、ASCIIトークンでのみマッチングが発生する)語彙にのみ適しています。
  3. Unicode正規大文字・小文字畳み込み(Unicode canonical case fold)。大文字・小文字畳み込みであり、Unicode正規正規化の適用も行われたテキストの比較。このステップは、ASCIIではない文字を認めている語彙に対して大文字・小文字を区別しないことが望ましい場合に適しています。
  4. Unicode互換大文字・小文字畳み込み(Unicode compatibility case fold)。大文字・小文字畳み込みであり、Unicode互換正規化の適用も行われたテキストの比較。
3.1.2.1 デフォルトの正規化ステップ

デフォルトの正規化ステップでは、Unicode正規化は適用されず、大文字・小文字畳み込みも行われません。これは、大文字・小文字の違いも、比較対象の元の文字列のコードポイントも区別することを意味します。コンテンツの作成者は、異なるトークンがマッチすると予想される場合に、影響を受けるテキストをエンコードするために、一貫性がある大文字・小文字と、一貫性がある文字シーケンスを用いていることを認識し、確保する必要があります。

3.1.2.2 ASCII大文字・小文字畳み込み正規化ステップ

ASCII大文字・小文字畳み込み正規化ステップは、ASCIIの範囲のみの大文字・小文字畳みを実行します。

文字列ごとに、次のステップを実行します。

  1. 文字列内のUnicodeコードポイントごとに、コードポイントがU+0041 LATIN CAPITAL LETTER AU+005A LATIN CAPITAL LETTER Zの間にある場合は、それをU+0061 LATIN LOWERCASE LETTER AU+007A LATIN LOWERCASE LETTER Zの間の対応するコードポイントに置き換え、そうでない場合は、元のコードポイントを保持します。
  2. 結果の文字列を返します。
3.1.2.3 Unicode正規大文字・小文字畳み込み正規化ステップ

ASCIIではない文字を認めている語彙(ほとんどの新しい語彙を含んでいるべき)を含んでいて、大文字・小文字を区別したくない仕様では、このステップを規定すべきです(SHOULD)。これは推奨されません。

大文字・小文字畳み込みは、入力コードポイントのシーケンスの影響を受けます。また、単独で、非正規化コードポイントのシーケンスを生成することもできます。その結果、この正規化ステップには、大文字・小文字畳み込みの前と後の両方のUnicode正規化が含まれます。このステップは、[Unicode]要件D145と一貫性があります。

文字列ごとに、次のステップを実行します。

  1. 文字列のUnicode正規化を実行してNFDを形成します。これにより、文字列のエンコードの正規バリエーションがなくなります。
  2. 結果の文字列にUnicode完全の大文字・小文字畳み込みを実行します。
  3. 結果の文字列をUnicode正規化してNFCを形成します。
  4. 結果を返します。
3.1.2.4 Unicode互換大文字・小文字畳み込み正規化ステップ

ASCIIではない文字を認めていて、Unicode互換同等とマッチする必要がある語彙を含んでいる仕様では、この正規化ステップを用いるかもしれません。互換正規形(NFKCNFKD)は、テキストの意味、見た目、処理を変えるため、このステップはほとんどのウェブのアプリケーションでは用いるべきではありません(SHOULD NOT)。

警告

大文字・小文字畳み込みは、入力コードポイントのシーケンスの影響を受けます。これは、非正規化コードポイントのシーケンスを生成することもできます。その結果、この正規化ステップには、NFKD形式(これは、互換マッピングを提供する)とNFD形式の両方を含む、複数のUnicode正規化の使用が含まれます。このステップは、[Unicode]要件D146と一貫性があります。

文字列ごとに、次のステップを実行します。

  1. 文字列のUnicode正規化を実行してNFDを形成します。これにより、文字列のエンコードの正規バリエーションがなくなります。
  2. 結果の文字列にUnicode完全の大文字・小文字畳み込みを実行します。
  3. 結果の文字列をUnicode正規化してNFKDを形成します。
  4. 結果の文字列にUnicode完全の大文字・小文字畳み込みを実行します。これにより、互換マッピングによって生成されるアーティファクトがなくなります。
  5. 結果の文字列にUnicode正規化を実行してNFKCを形成します。これにより、大文字・小文字畳み込みによって生成される残りのアーティファクトがなくなります。
  6. 結果を返します。

3.1.3 Unicodeコードポイントのシーケンスへの変換

[C] コンテンツの作成者は、Unicode文字エンコーディング(一般的にウェブではUTF-8)で資源を入力し格納すべきです(SHOULD)。

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

[C] 特定の文字のマッピングが意味に干渉ない限り、コンテンツの作成者は、レガシー・エンコードが行われたテキストや資源をUnicodeに変換するときに正規化トランスコーダを選択すべきです(SHOULD)。

正規化トランスコーダ(normalizing transcoder)は、レガシー文字エンコーディングからUnicodeへの変換を行い、かつ、結果がUnicode正規形C(NFC)であることを保証するトランスコーダです。ほとんどのレガシー文字エンコーディングに対して、正規化トランスコーダを構築することができます(任意のトランスコーダの後に正規化システムを用いることによって)。レガシー文字エンコーディングレパートリーにUnicodeでは表せない文字が含まれている場合は、これを行うことはできません。正規化トランスコーダはNFCの文字シーケンスのみを生成しますが、変換された文字シーケンスはインクルード正規化されない可能性があります(例えば、合成可能記号で始まる場合など)。

ウェブ上のドキュメントのフォーマットは付加的な外部資源(例えば、HTMLドキュメントに適用されているCSSスタイルシートなど)と相互作用を行ったり処理したりすることが多いため、さまざまな文字エンコードを用いたドキュメント間で値をマッチングさせる場合は、一貫性があるテキストの表現が重要になります。正規化トランスコーダを用いることにより、レガシー・エンコードが行われたドキュメントを、ほとんどの言語で通常予想されるUnicode文字シーケンスとマッチさせることで、相互運用性を確保できます。

ウェブで用いられているほとんどのトランスコーダは出力としてNFCを生成しますが、そうでないものもあります。これは通常、トランスコーダが情報源のレガシー文字エンコーディングとのラウンド・トリップの互換性を保ったり、その他の文字の区別を保持したり、ユーザ・エージェントで用いられている他のトランスコーダとの一貫性を保つためです。これは、エンコーディング仕様[Encoding]およびその他のさまざまな重要なトランスコーディングの実装に、多くの非正規化トランスコーダが数含まれていることを意味します。実際、Unicodeのほとんどの互換文字はレガシー・エンコーディングからのラウンド・トリップ変換のためだけに存在しており、これらの多くにNFCのシングルトン正規マッピングがあります。このドキュメントの前半 [U+212B ANGSTROM SIGN]を用いてこの例を示しました。

ほとんどのトランスコーダはNFCの出力を生成し、すべての文字に対してNFCを生成するとは限らないトランスコーダでも、圧倒的多数の文字に対してNFCを生成することに注意してください。特に、合成済形式が存在している場合に分解形式を生成したり、正規化されたシーケンスとは異なる合成可能文字シーケンスを生成したりする一般的に用いられているトランスコーダはありません(これは[Encoding]のすべてのトランスコーダに当てはまります)。

[S] 仕様はUnicode文字エンコーディングを認めなければなりません(MUST)。

[S] 仕様はデフォルトの文字エンコーディングを規定しなければならず(MUST)、デフォルトのエンコーディングとしてUTF-8を規定すべきです(SHOULD)。

[S] 仕様はUTF-8以外のエンコーディングを認めないべきです(SHOULD)。

一般的にレガシー文字エンコーディングは、ウェブでの有効性を失っています。新しい仕様では、最初からUnicodeエンコーディングをサポートし、デフォルトをUnicodeエンコーディング(通常はUTF-8)とし、可能であれば、他のエンコーディングの使用を認めないようにする必要があります。これにより、相互運用性が促進されるだけでなく、文字とデータの表現の無意味なバリエーションの範囲が削減されます。

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

ほとんどのドキュメントのフォーマットとプロトコルは、文字をエスケープ・シーケンスとしてエンコードしたり、テキストなどの外部データを資源に含めたりする手段を提供しています。これは[CHARMOD]の4.6項と上記で詳細に論じています。

マッチングを実行する際に、マッチングが適切に成功する(または、失敗する)には、いつ文字エスケープを解釈すべきかを知ることが重要です。通常、エスケープ、参照、およびインクルードは、これらの構文が、エンコードし難いシーケンスをドキュメントに便利に入力できるようにしつつも、文字が、問題のドキュメントにコードポイントのシーケンスとして直接エンコードされているかのように動作できるようにするために存在しているため、マッチング(またはマッチに依存した処理)を実行する前に処理または展開されます。

これが複雑になりえる分野の1つは、構文コンテンツと自然言語コンテンツがどのように相互作用するかを判断することです。例えば、次のHTMLの断片を見てください。

技術的には、 ̀[U+0300 COMBINING GRAVE ACCENT]という合成可能記号は、先行する引用符と合成されますが、HTMLは、その文字を考慮せずに(エンティティーとしてエンコードされているかどうかにかかわらず)、HTML構文の一部を形成します。

資源にマッチング操作を行う場合、一般的な規則は、ユーザが相互作用しているのと同じ「レベル」でエスケープを展開することです。例えば、上記の例を見てみると、HTMLのソースを表示するツールは、エスケープ・シーケンス&#x300;をアンパサンドで始まる文字列として表示します。対照的に、JavaScriptプログラムは、ブラウザによるドキュメントの解釈で処理を行い、idという属性の値としてのU+0300という文字とマッチします。

ドキュメントのフォーマットの構文を処理する場合、エスケープは通常、フォーマットの処理規則で明示的に禁止されている場合を除き、構文の処理前に、それらが表す文字シーケンスに変換されます。これにより、資源はすべての種類の文字をその資源の構文構造に含めることができます。

場合によっては、前処理のエスケープにより問題が生じます。例えば、HTMLドキュメントを解析する前に&lt;というシーケンスを展開すると、ドキュメント・エラーが発生します。

3.1.5 正規化に関する追加の留意点

特定のUnicode正規形は、コンテンツ作成者にとって常に適切または利用可能であるとは限らず、ユーザのテキスト・エンコーディングの選択は、データの下流の利用者には明確ではないかもしれません。このドキュメントで示しているように、テキストを入力または交換するときにコンテンツの作成者やアプリケーションが同じ意味の値を表すために選択できる方法は多様です。正規化により、ユーザが意図的に適用した区別を削除できます。したがって、マッチング・アルゴリズムでは、文字列の大文字・小文字畳み込みマッチングを行うときにUnicode正規化の使用を規定し、その後にそのアルゴリズムに対して内部的にのみ規定します。コンテンツに正規化を課すことは、ユーザや実装者にとっての障壁となる可能性があります。したがって、

[S] 仕様では、特定の語彙のエンコーディング、格納、または交換のためのUnicode正規形を規定すべきではありません(SHOULD NOT)。

[I] 利用者やコンテンツ自体は、非正規化された表現に依存している可能性があるため、実装では、コンテンツのUnicode文字エンコーディングへのトランスコード、大文字・小文字変換畳み込み、ユーザ主導による変更などのテキスト変換の副作用として行う必要のある場合を除き、交換、読み取り、解析、処理中の構文コンテンツまたは自然言語コンテンツの正規形を変更してはなりません(MUST NOT)。

[I] オーサリング・ツールは、資源を正規化する手段を提供し、特定の資源がUnicode正規形Cではない場合にユーザに警告すべきです(SHOULD)。

特定の正規形のテキストの格納と交換を必要とする仕様は、§3.1.5.1 ドキュメントのフォーマットでの正規化を規定するときの要件の要件に対処する必要があります。

追加要件が必要な具体的で明確な理由がない限り、仕様で、フォーマットやプロトコルが正規形でのデータの格納や交換を要求することは一般的に推奨されません。ウェブ上の多くのドキュメントのフォーマットには正規化は必要ないため、コンテンツの作成者は非正規化文字シーケンスに頼る可能性があります。正規化ステップは、そのようなコンテンツに悪影響を及ぼす可能性があります。

正規正規形(NFC形式またはNFD形式)は、それを適用したテキストの意味と表現の保持を目的としています。これは常に当てはまるわけではなく、それが正規化を推奨しない理由の1つです。NFCには、ほとんどすべてのレガシー・データ(Unicodeエンコーディングに1対1でトランスコードされていることが自明であれば)に加え、現在のソフトウェアで作成したデータや、ほとんどの(しかし、全部ではない)キーボードでユーザが入力したデータが、すでにこの形式であるという利点があります。NFCには、少しコンパクトになるという利点があり、文字と書記素との関係に関して、ほとんどの言語でのユーザの期待によくマッチします。

[S] 仕様では、互換正規形(NFKC、NFKD)を規定すべきではありません(SHOULD NOT)。

[I] 実装では、エンドユーザが特に要求しない限り、互換正規形(NFKC、NFKD)を適用してはなりません(MUST NOT)。

互換正規形(NFKC形式およびNFKD形式)は、構造を変え、テキストの意味を大きく失わせます。ユーザは、意図的にUnicodeの互換マッピングの文字を用いたり、Unicodeに変換すると互換マッピングを持つレガシー文字エンコーディングの文字を用いたりすることもあります。これは、コンテンツの作成者側は意図的であると考える必要があります。NFKC/NFKDは、「検索」操作や自然言語コンテンツの文字列検索に役立つことがありますが、互換性の違いを消去することは有害です。

ウェブのコンテンツは一般的に正規化状態が不明なため、仕様の開発者側ではNFCの要求に特別な注意が必要です。これらのケースでは、非正規化コンテンツの境界条件とエラー条件を慎重に検討し、明確に規定する必要があります。

[S] 正規同等でありながらも素であるUnicode文字シーケンスがセキュリティ上の問題を表す場合は、仕様で警告を文書化または提供しなければなりません(MUST)。

[C] コンテンツの作成者は、コンテンツで可能な場合は常にUnicode正規形C(NFC)を用いるべきです(SHOULD)。NFCは常にコンテンツに適しているわけではなく、一部の言語ではコンテンツの作成者に利用可能でさえないことに注意してください。

[C] コンテンツの作成者は、フォーマットや実装によって実行されるマッチングにUnicode正規形が含まれている場合であっても、マッチングを容易にするために、常に一貫性があるUnicode文字シーケンスを用いてテキストをエンコードすべきです(SHOULD)。

一貫したコンテンツの処理を行うために、コンテンツの作成者は、一貫したコードポイントのシーケンスを用いて同じテキストを表すべきです。コンテンツは正規形式でありえ、非正規化された(しかし、有効な)Unicode文字シーケンスを用いている可能性もありますが、表示が一致しないため、実装は異なるシーケンスを異なるものとして処理します。一貫性がある選択、アクセス、抽出、処理、または表示を確保にするための最良の方法は、常にNFCを用いることです。

[C] コンテンツの作成者は、基底文字が先行しない合成可能記号を資源に含めるべきではありません(SHOULD NOT)。

これには例外があります。例えば、文字のリスト([Unicode]文字のリストなど)を作成するときに、作成者は、対応する基底文字なしに合成可能記号を用いたいと考えるかもしれません。しかし、基底文字なしに合成可能記号を用いると想定外の表示になったり、合成可能記号を隣接する構文コンテンツやその他の自然言語コンテンツと合成するという甘い実装によって処理上の問題が発生したりする可能性があります。例えば、HTMLのclass属性値の開始文字として、 ́[U+0301 COMBINING ACUTE ACCENT]などの合成可能記号を用いれば、クラス名がエディタに正しく表示されず、編集が困難な可能性があります。

一部の推奨される基底文字には、 [U+25CC DOTTED CIRCLE](基底文字を表示する必要がある場合)や  [U+00A0 NO-BREAK SPACE](基底文字を非表示にする場合)があります。

コンテンツの作成者は、常にこれらのガイドラインに従うわけではないため、

[S] 語彙の仕様は、(言語に何らかのインクルード・メカニズムがある場合)構文コンテンツと文字データの間の境界に加え、エンティティーの境界を定義しなければなりません(MUST)。これには、言語のインスタンスを処理する場合に、コンテンツの処理時またはマッチング時に競合を引き起こしうる境界を含める必要がありますが、任意の文字を表すように設計された文字エスケープは認められます。

3.1.5.1 ドキュメントのフォーマットで正規化を規定するときの要件

格納、転送、処理のためにUnicode正規化が仕様で要求されている場合、その仕様の作成者とその仕様の実装者は、いくつかの追加の留意事項に取り組む必要があります。

[S] 操作によって、正規化されたテキストの入力から非正規化された出力が生成されうる場合、仕様は、その結果の出力を正規化する必要があるかどうかを定義しなければなりません(MUST)。仕様では、正規化の実行は一部の操作ではオプションであると記述することができます。その場合、正規化を実行するのがデフォルトであるべきで(SHOULD)、正規化をオフにするための明示的なオプションを用いるべきです(SHOULD)。

[S] 正規化を必要とする仕様は、正規化の実装をオプションにしてはなりません(MUST NOT)。 実装よって正規化するものと、そうでないものがある場合には、相互運用性は達成できません。

正規化を実行するために必要な実装は、次の要件を考慮する必要があります。

[I] 実装で、最初に検査によってテキストが正規形であることを確認したか、テキスト自体を再正規化したかのいずれかでない限り、正規化に依存した操作を実行してはなりません(MUST NOT)。これらの規則に従わない私的なシステム内では、私的な合意を作成することができますが(MAY)、外部から見える結果は、規則に従った場合と同じでなければなりません(MUST)。

[I] テキストを変更し、正規化に依存した操作を実行する正規化のテキスト処理コンポーネントは、その後の正規化に依存した操作が常に正規化テキストを扱っているかのように動作するように、正規化が個々の変更後に行われたかのように動作しなければなりません(MUST)。

[I] オーサリング・ツールの実装では、処理、表示、または交換を妨げる可能性がある合成可能記号で始まる構文コンテンツの入力や作成をユーザに警告するか、防止すべきです(SHOULD)。

3.1.6 大文字・小文字畳み込みに関する追加の留意点

文字列の同一性マッチングにおける重要な留意点の1つは、比較が大文字・小文字を区別するかしないかです。

[C] コンテンツの作成者は、大文字・小文字折り畳みマッチングがフォーマットや実装でサポートされている場合であっても、マッチングを容易にするために、常に一貫性がある大文字、小文字、大文字・小文字混在のフォーマットを用いて識別子を綴るべきです(SHOULD)。

3.1.6.1 大文字・小文字を区別するマッチング

[S] 大文字・小文字を区別するマッチングは、ユーザ定義の値を含む構文コンテンツのマッチングに推奨されます(RECOMMENDED)。

通常、語彙では、コンテンツの作成者とユーザにとっての予測可能性が重視されます。大文字・小文字を区別するマッチングは、一般的に、基礎となるUnicodeコードポイントのシーケンスの比較で構成されているため、実装するのが最も容易で、混乱の可能性が最も低いです。これは、言語固有の大文字・小文字マッピングなどの留意事項の影響を受けないため、上記のトルコ語の例などの、単語を構文コンテンツに含めていたドキュメントの作成者にとっては、それほど驚くことではありません。

通常、大文字・小文字を区別しないことは、テキストを検索する機能を実行するなどの、自然言語コンテンツの処理のために予約されています。しかし、大文字・小文字を区別しないことが望ましい場合もあります。大文字・小文字を区別しないマッチングが必要な場合、形式言語で考慮する必要があるいくつかの実装上の選択があります。

3.1.6.2 大文字と小文字を区別しないUnicodeマッチング

[S] Unicodeの基本ラテン(ASCII)の範囲を超える語彙で大文字・小文字を区別しないマッチングを定義する仕様は、Unicode完全の大文字・小文字畳み込みマッチングを規定しなければなりません(MUST)。

[S] 仕様では、ユーザ定義の値に対してUnicodeの全ての範囲を認めるべきです(SHOULD)。

語彙は一般的に、最も広い範囲の言語や文化によって不都合なく使用できるように、広い範囲のUnicode文字、特にユーザ指定の値を認めるべきです。その結果、大文字・小文字折り畳みなどのテキスト操作では、選択した部分のみでなく、Unicodeの全範囲に対処する必要があります。大文字・小文字を区別しないマッチングが望ましい場合、それはUnicodeの大文字・小文字折り畳みを用いることを意味します。

Unicodeシンプルの大文字・小文字折り畳み形式は、ウェブの文字列同一性マッチングには適していません。

3.1.6.3 ASCIIの大文字・小文字を区別しないマッチング

[S] Unicodeの基本ラテン(ASCII)サブセットに限定されている語彙で大文字・小文字を区別しないマッチングを定義する仕様では、ASCIIの大文字・小文字を区別しないマッチングを規定できます(MAY)。

語彙がASCIIに限定されており、ユーザ定義の名前や識別子を認めない形式言語では、ASCIIの大文字・小文字を区別しないマッチングを規定できます。その一例がHTMLで、HTMLは、その仕様で定義している要素名と属性名に対するASCIIの大文字・小文字を区別しない比較の使用について定義しています。

すべてのトークンと識別子が仕様で直接定義されており、これらの識別子やトークンがUnicodeの基本ラテンのサブセットのみを用いている場合に限り、語彙は「ASCIIのみ」と見なされます。ユーザ定義の識別子が認められていれば、Unicode文字の全範囲(セキュリティ上または交換上の懸念から、必要に応じて制限される。[UTR36]を参照)が認められ、Unicodeの大文字・小文字を区別しない方法を同一性マッチングに用いるべきです。

識別子や値により広い範囲のUnicodeを認めているドキュメントのフォーマットやプロトコル内にASCIIのみの語彙を置くことができます。例えば、[CSS-SYNTAX-3]は、識別子と値にUnicodeの全範囲を使用できるような方法でCSSのスタイルシートのフォーマットを定義しています。しかし、CSSの仕様は、常にASCIIの範囲のサブセットを用いてCSSキーワードを定義しています。多くのスタイルシートにはASCIIではない識別子やデータ値が含まれていますが、CSSの語彙はASCIIのみです。

3.1.6.4 言語固有の調整

ロケール固有または言語固有の調整は、自然言語処理操作の一部である場合に最も適しています(これはこのドキュメントの範囲外です)。大文字・小文字マッピングや大文字・小文字畳み込みの言語固有の調整は、一般的な大文字・小文字畳み込み規則とは異なる結果をもたらすため、予測可能性が重視される形式言語では避けるべきです。

[S] 語彙で大文字・小文字を区別しないマッチングを定義する仕様は、言語依存の大文字・小文字を区別しないマッチングを規定すべきではありません(SHOULD NOT)。

[S] 言語依存の大文字・小文字を区別するマッチングが規定されている場合、Unicodeの大文字・小文字マッピングは言語に応じて調整すべきであり(SHOULD)、それぞれの調整に用いる言語の情報源が規定されていなければなりません(MUST)。

マッチングした2つの文字列は異なる言語のものでありえ、さらに、3つ目の言語のコンテキストで表示されることもあります。したがって、大文字・小文字畳み込みにどの言語を用いるかは、アプリケーションとユーザの期待に依存します。

言語情報を取得、検証、管理するのは困難な可能性があり、結果として得られる操作によって、使用している言語設定やマッチングが実行されるシステムの設定により、ユーザが不満を感じたり、ユーザによって失敗する場合もあれば成功する場合もある結果となりえるため、言語固有調整は形式言語にはお勧めできません。

[S] 言語固有の操作には、必要に応じて言語固有の大文字・小文字畳み込みを含むべきです(SHOULD)。

例えば、text-transformというCSSの操作は、大文字・小文字マッピングの文字列に用いた場合に、言語依存です。

Unicodeの大文字・小文字畳み込みは、ドキュメントのフォーマットとプロトコルにとって望ましい大文字・小文字を区別しないマッチングですが、それでも、デフォルトとはマッピングが異なるコンテンツの作成者や言語のユーザは、彼らが話す言語と概ね予想が一致しているため、結果に驚く可能性があります。

ほとんどのプログラミング言語と操作環境では、それぞれのロケール・ベースのAPIを用いて言語固有の調整にアクセスするため、言語依存の文字列比較はしばしばロケール依存(locale-sensitive)と呼ばれます。例えば、Javaプログラミング言語のjava.text.CollatorクラスまたはJavaScriptのIntl.Collatorを参照してください。

3.1.7 追加のマッチの調整

[S] 仕様は、マッチング・プロセスの一部として行われる追加の調整を明確に定義しなければなりません(MUST)。

特定の語彙のマッチングを支援するために追加で調整を含めたいと考える仕様があるかもしれません。その例には、2項で説明した追加のテキストの違いを取り除くこと、構文の一部である文字を一緒にマッピングするか取り除くこと、または空白の切り取りを行うことなどが含まれる可能性があります。

調整の追加により、さまざまな言語がUnicodeで表現される方法が妨げられないようにする必要があります。例えば、テキストを分解した後に合成可能文字をすべて削除して、文字からアクセント記号を削除しようとすると、合成可能記号に依存している言語が壊れます。その一例は、例2のデーヴァナーガリーのテキストでしょう(また、このようなプロセスでは、潜在的なアクセントをすべて削除できず、テキストの意味と表現に悪影響を及ぼすでしょう。)

4. その他のマッチングおよび処理上の留意点

形式言語の文字列とトークンのマッチングがこのドキュメントの主な関心事ですが、単なる文字列の同等性にとどまらない別の種類のマッチングについて仕様で検討する必要がある場合があります。

4.1 正規表現

[S] 正規表現構文を定義する仕様は、少なくとも[UTS18]に基づく基礎Unicodeレベル1をサポートしなければならず(MUST)、拡張または調整を行った(レベル2と3)をサポートすべきです(SHOULD)。

正規表現の構文は、部分的にしか認識されていない値や、異なっている可能性を予測できる値をユーザが指定できるため、フォーマットやプロトコルの定義に役立つことがあります。このドキュメントのさまざまな項で見てきたように、Unicodeで文字をエンコードできるさまざまな方法にはバリエーションがあり、それにより、表現における文字列の指定やマッチングが妨げられる可能性があります。例えば、文字数のカウントは、用いられているUnicodeコードポイントの数ではなく、書記素の境界に依存する必要があります。大文字・小文字を区別しないマッチングでは、大文字・小文字畳み込みのバリエーションを考慮する必要があります。あるいは、処理対象の表現やテキストのUnicode正規化を考慮する必要があるかもしれません。

Unicodeの正規表現レベル1のサポートには、エスケープの使用によるものなど、正規表現でUnicodeコードポイントを規定したり、Unicodeの文字プロパティーやほとんどの正規表現構文に共通する特定の種類の境界にアクセスしたりする機能が含まれています。

レベル2では、これをいくつかの重要な機能、特に特定の種類の書記素クラスタの境界上のテキストを選択し、大文字・小文字変換をサポートする機能(上記で広く述べた2つのトピック)で拡張しています。レベル3は、ロケール[LTLI]ベースの正規表現の調整を提供しており、これは形式言語ではあまり有用ではありませんが、自然言語コンテンツの処理には有用でありえます。

A. 最後に公開されたバージョン以後の変更

2018年4月20日のワーキングドラフト以後のこのドキュメントに対する変更点は、github commitログで入手可能です。

B. 謝辞

W3C国際化ワーキンググループおよび利害団体、そして他の方々が、多くの指摘と提案を提供してくださいました。ワーキンググループは、Mati Allouche、Ebrahim Byagowi、John Cowan、Martin Durst、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; M. Davis. IETF. September 2009. IETF Best Current Practice. URL: https://tools.ietf.org/html/bcp47
[CHARMOD]
Character Model for the World Wide Web 1.0: Fundamentals. Martin Durst; Francois Yergeau; Richard Ishida; Misha Wolf; Tex Texin et al. W3C. 15 February 2005. W3C Recommendation. URL: https://www.w3.org/TR/charmod/
[CHARREQ]
Requirements for String Identity Matching and String Indexing. Martin Durst. W3C. 15 September 2009. 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 Jagenstedt; 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. 21 July 2015. W3C Note. URL: https://www.w3.org/TR/html-bidi/
[HTML5]
HTML5. Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Theresa O'Connor; Silvia Pfeiffer. W3C. 27 March 2018. W3C Recommendation. URL: https://www.w3.org/TR/html5/
[INTERNATIONAL-SPECS]
Internationalization Best Practices for Spec Developers. Richard Ishida. W3C. 7 October 2016. 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. Felix Sasaki; Addison Phillips. W3C. 23 April 2015. W3C Working Draft. URL: https://www.w3.org/TR/ltli/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. January 2005. Internet Standard. URL: https://tools.ietf.org/html/rfc3986
[UAX11]
Unicode Standard Annex #11: East Asian Width. Ken Lunde 小林劍.URL: https://www.unicode.org/reports/tr11/
[UAX15]
Unicode Normalization Forms. Mark Davis; Ken Whistler. Unicode Consortium. 26 May 2017. Unicode Standard Annex #15. URL: https://www.unicode.org/reports/tr15/tr15-45.html
[UAX29]
Unicode Standard Annex #29: Unicode Text Segmentation. Mark Davis.URL: https://www.unicode.org/reports/tr29/
[UAX35]
Unicode Locale Data Markup Language (LDML). Mark Davis; CLDR committee members. Unicode Consortium. 15 March 2017. Unicode Standard Annex #35. URL: https://www.unicode.org/reports/tr35/tr35-47/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. 15 November 2006. 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. 20 February 2014. W3C Candidate Recommendation. URL: https://www.w3.org/TR/css-syntax-3/
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; Francois Yergeau et al. W3C. 26 November 2008. W3C Recommendation. URL: https://www.w3.org/TR/xml/