万维网字符模型:字符串匹配

W3C 首次公开工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-charmod-norm-20260716/
最新发布版本:
https://www.w3.org/TR/charmod-norm/
最新编辑草案:
https://w3c.github.io/charmod-norm/
历史记录:
https://www.w3.org/standards/history/charmod-norm/
提交历史记录
编辑:
Addison Phillips特邀 专家
反馈:
GitHub w3c/charmod-norm拉取请求新建议题开放议题

摘要

本文以万维网字符模型 1.0:基础[CHARMOD]为基础,为规范 作者、软件开发者和内容开发者提供有关万维网上字符串同一性 匹配的通用参考,从而提高互操作性。

本文档的状态

本节描述本文档在发布时的状态。当前W3C 出版物的列表以及本技术报告的最新修订版可在 W3C 标准与草案 索引中找到。

为了便于跟踪评论,请针对每条评论分别提出议题或发送电子邮件,并使用 URL 指向 您所评论的章节。

本文档由国际化 工作组采用 推荐标准 路径发布为首次公开工作草案。

发布为 首次公开工作草案并不意味着 W3C 及其成员认可本文档。

本文档是一份草案,可能随时由其他 文档更新、取代或废弃。除作为尚在进行中的工作外,不宜引用本文档。

本文档由一个依据 W3C 专利 政策运作的工作组编制。 W3C 维护着一份 所有专利 披露的公开列表, 其中列出了与该工作组交付成果相关的专利披露;该页面还包含 披露专利的说明。任何实际 知晓某项专利,并认为该专利包含 必要权利要求的个人, 都必须按照 W3C 专利政策第 6 节披露相关信息。

本文档受 2025年8月18日 W3C 流程文档约束。

1. 简介

1.1 目标与范围

万维网字符模型的目标是依照 W3C 的普遍访问目标,促进所有人使用 Web, 无论其语言、文字、书写系统或文化惯例如何。实现此目标的一项基本 先决条件,是能够以明确定义且易于理解的方式传输和处理世界各地 使用的字符。

本文档以万维网字符模型:基础 [CHARMOD]为基础。 理解该文档中的概念,对于成功理解和应用 本文档非常重要。

万维网字符模型的这一部分涵盖字符串 匹配,即规范或实现定义两个字符串值 彼此相同或不同的过程。它描述了语义等价的文本 可以采用不同编码方式的情形,以及这对形式语言中重要的匹配操作 造成的影响(例如构成 Web 的格式和 协议所使用的语言)。

本规范的主要目标受众是 W3C 规范 开发者。其他 W3C 规范可以引用本规范或其中的部分内容,并且本规范为 W3C 规范以及其他规范 定义一致性标准。

本规范的其他受众包括软件开发者、 内容开发者以及 W3C 以外的规范作者。 软件开发者和内容开发者实现并使用 W3C 规范。本规范为实现和使用 W3C 规范的实现(软件)和内容定义了一些一致性标准。 它还有助于软件开发者和内容 开发者理解 W3C 规范中与字符相关的规定。

本规范所描述的字符模型,为规范作者、 软件开发者和内容开发者提供了一个通用参考,以便在 万维网上一致且可互操作地处理文本。通过协同工作,这三个群体可以构建一个 全球皆可访问的 Web。

1.2 本文档的结构

本文档通过定义文档格式中字符串 同一性匹配的规则和过程,规定了与该问题相关的 Web 基本构建块之一。 这些规则面向文档格式中使用的标识符和结构化标记(句法内容), 旨在确保对各项内容进行一致处理,并且 面向规范作者。本 节面向实现者。

本文档分为两个主要章节。

第一节阐述了 字符串匹配所涉及的问题、Unicode 和大小写 折叠对这些问题的影响,并概述了可用于解决这些问题的各种事项和 规范化机制。

第二节提供了 用于形式语言中的字符串同一性匹配 要求和建议,例如 W3C 规范定义的许多 文档格式。这主要 涉及确保 Web 正常运行,并为文档 作者提供一致的结果。

1.3 背景

本节提供本规范所讨论主题的一些 历史背景。

字符模型的核心是通用字符集 (UCS),它由Unicode 标准 [Unicode]与 ISO/IEC 10646 [ISO10646]共同定义。 在本文档中,Unicode 用作通用字符集的同义词。一个成功的 字符模型,使使用世界各地书写 系统、文字和语言(以及不同平台)编写的 Web 文档能够被全球 Web 用户交换、阅读和搜索。

Unicode 标准的前几章 [Unicode]提供了有用的背景资料。

有关为本规范重要部分的制定 提供依据的要求,请参阅字符串同一性 匹配与字符串索引要求 [CHARREQ]。

1.4 术语与记法

本节包含本文档特有的术语和记法。

Web 建立在基于文本的格式和协议之上。为了 有效描述字符串匹配或搜索,有必要 建立一套术语,使我们能够讨论给定格式或协议中的不同类型 文本,因为它们的要求和 细节差异很大。

Unicode 码位(或“码位”)是指分配 给每个 Unicode 字符的数值。Unicode 码位的范围从 00x10FFFF。(有关字符编码术语的 更深入讨论,请参阅 [CHARMOD] 的第 4.1 节。)

Unicode 码位表示为 U+hhhh,其中 hhhh 是至少四位、至多六位的 十六进制数字序列。例如,字符 [U+20AC EURO SIGN] 的码位是 U+20AC,而字符 😺 [U+1F63A SMILING CAT FACE WITH OPEN MOUTH] 的码位是 U+1F63A

本文档示例中使用的某些字符,可能无法在您的特定设备或 显示器上按预期显示。这通常是因为本地未安装特定文字的字体,或由于您的 特定呈现系统存在其他限制。本文档使用 Web 字体,为 许多非拉丁字符提供后备字形,但您的设备可能不支持显示该字体。在 可能的范围内,编辑者已尽力确保这些示例仍然可以理解。

旧式字符编码是一种 不对 Unicode 字符集中完整字符集合进行编码的字符编码形式。

转码器是一种在两种字符编码之间转换 文本的过程。在本文档中,它最常指 从旧式字符编码 转换为 Unicode 编码 形式(例如 UTF-8)的过程。

自然语言是人类使用的口头、书面或手势 交流方式(另请参阅 此处 [LTLI])

句法内容是文档格式 或协议中属于该格式或协议结构的任何文本。此定义包括 通常被视为“标记”的值,也可以包括其他值,例如 HTTP 标头中的字段 名称。句法内容由构成格式或协议结构的所有字符组成。 例如,<>(以及它们所包围的元素名称和各种属性)是 HTML 文档句法内容的一部分。

句法内容通常由一项或多项规范定义,包括给定协议或格式已定义的 保留关键字,以及由文档作者定义、用于形成文档结构 (而非文档“内容”)的字符串标记和标识符。

词汇表是保留关键字的列表,以及/或者用于在格式或 协议中分配用户提供的值(例如标识符)的规则。这可以包括对不同位置中 可出现字符的范围、顺序或类型的限制。

例如,HTML 定义其元素和属性的名称以及枚举属性 值,从而定义 HTML 句法内容的“词汇表”。另一个示例 是 ECMAScript,它限制可以出现在标识符或变量名称开头或主体中的字符范围。 对于其他情况,例如字符串字面量的值,它采用不同的规则。

词汇表中的值分为两大类:一类供人类 查看、阅读或交互(因此可能包含自然语言文本); 另一类供应用程序或协议内部使用,不用于人机交互。

面向用户的标识符是由用户在词汇表中定义或分配的标识符,并且至少可能向 最终用户显示(因此属于可本地化内容)。

应用程序内部标识符是由用户在词汇表中定义或分配的标识符,它在文档 格式或协议内部使用,不用于人机交互。此类值通常不属于可本地化内容

用户提供的值词汇表中未保留的句法内容,由用户 分配,有别于给定格式或协议中的保留关键字。用户通常 希望其用户提供的值可以是其首选自然语言中的单词或短语。这就是 [CHARMOD] 建议 “规范不应任意排除从 U+0000U+10FFFF (含)完整 Unicode 码位范围内的码位”的原因。

可本地化 内容是指用作人类可读文本的文档内容,而不是构成 文档结构一部分的任何周围或嵌入式句法内容。请注意, 句法内容中可以嵌入可本地化内容,例如当 [HTML] img 元素具有包含图像说明的 alt 属性时。

在本文档的语境中,资源是给定的文档、文件或 协议“消息”,其中既包括可本地化内容,也包括 环绕或包含这些内容的标识符等句法内容。例如,在还包含一些 CSS 和若干嵌入 JavaScript 的 script 标签的 HTML 文档中,将整个 HTML 文档视为 一个文件时,它就是一项资源。此术语有意与 [RFC3986] 中使用的“资源”一词相似,尽管这里对该 术语的使用较为宽泛。

字素是某些文本视觉表示中的一个或多个 字符序列,普通用户会将其视为一个单独的单位(字符)。 字素对于排序或文本选择等许多文本操作都很重要, 因此必须能够计算每个用户感知字符之间的 边界。Unicode 在Unicode 标准附录 #29:文本分段 [UAX29]中定义了 计算字素的默认机制,并将这种近似称为字素簇。默认字素簇定义了两种类型。 除非另有说明,本文档中的字素 簇是指扩展默认字素 簇。(Unicode 标准第 2 节也讨论了字素簇, [Unicode]。另请参阅 Unicode 标准 8.0 版 第 2.11 节 结尾附近的内容)

由于不同自然语言有不同需求,字素簇 有时也可能需要定制。例如,斯洛伐克语用户可能 希望将默认的一对字素簇“ch”视为单个 字素簇。请注意,字符串内容的语言与 最终用户偏好之间的交互可能很复杂。

1.4.1 术语示例

本节说明上面定义的一些术语。为便于说明,我们将使用 以下小型 HTML 文件作为示例(添加了行号以供参考):

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

2 <head>

3   <meta charset="UTF-8">

4   <title>莎士比亚</title>

5 </head>

6 <body>

7   <img src="shakespeare.jpg" alt="威廉·莎士比亚" id="shakespeare_image">

8   <p>名字有什么&#x2019;意义?我们称之为玫瑰的花,换一个名字也会同样 芬芳。</p>

9 </body>

10 </html>

  • 黑色矩形内的所有内容(即此 HTML 文件中的内容)都是资源的一部分。
  • 在本例中,句法内容包括所有 HTML 标记。只有两个字符串属于句法 内容:第 4 行的单词“莎士比亚”和第 8 行的句子“名字有什么意义?我们 称之为玫瑰的花,换一个名字也会同样芬芳。”。(嵌入第 8 行句子中的 HTML 实体 &#x2019;属于 句法内容。)
  • 可本地化内容带灰色背景的蓝色粗体字显示。除了 非句法内容外,第 7 行的 alt 值(威廉·莎士比亚) 也是可本地化内容。
  • 用户提供的值以斜体显示。在本例中,第 7 行有 三个用户提供的值:img 标签的 srcaltid 属性值。此外,第 1 行的 lang 属性值和第 3 行的 charset 属性值也是 用户提供的值。
  • 词汇表红色 下划线显示。HTML 文档的词汇表,是 [HTML] 中定义的元素和属性(以及 某些属性值,例如上述示例中 dir 属性的 ltr 值)。

上述所有文本(文本文件中的所有文本)构成资源。给定资源可能 完全不包含可本地化内容 (例如由四个设置为橙色矩形样式的空 div 元素组成的 HTML 文档)。 资源也可能不包含任何句法 内容,而仅由可本地化内容组成:例如, 一个包含哈姆雷特独白的纯文本文件。还要注意, HTML 实体 &#x2019;出现在可本地化内容中,并同时属于该资源的 可本地化内容和句法内容。

1.5 一致性

除标记为非规范性的章节外,本规范中的所有编写指南、图表、示例和注释 均为非规范性内容。本规范中的其他所有内容均为规范性内容。

本文档中的关键词可以必须不得 可选建议应该不应 仅当它们像这里所示全部以 大写形式出现时,才应按照 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释。

本文档描述其他规范作者的最佳实践,以及 针对实现和内容作者的建议。这些最佳实践也可在 国际化工作组的文档规范开发者的国际化最佳实践 [INTERNATIONAL-SPECS]中找到, 该文档旨在作为 W3C 规范中所有国际化最佳实践的一般参考。

本文档中的最佳实践使用 [RFC2119] 关键词, 以明确国际化工作组对特定 建议的意图。遵循本文档中的建议,有助于避免在 W3C 的“广泛审查”流程中、实现期间或 作者生成的内容中出现问题。本文档本身不是规范性文档,并且可能不时 修订。

规范在满足以下条件时,可以声称符合本文档:

  1. 不违反任何前面带有 [S] 且命令词为 必须不得的一致性标准
  2. 对于命令词为应该不应建议的标准,记录任何偏离的原因
  3. 将实现符合本文档作为一项一致性要求
  4. 将内容符合本文档作为一项一致性要求

对规范提出的要求,可能会间接导致对声称符合这些规范的 实现或内容提出要求。

当本规范包含过程性描述时,应将其理解为规定 所需外部行为的一种方式。只要可观察行为不受影响,实现可以采用其他方式 实现相同结果。

2. 字符串匹配问题

Web 主要由基于字符数据的文档格式和协议 组成。这些格式或协议可视为一组资源,主要由 包含某种结构化标记或句法内容的 文本文件构成。处理此类句法内容或文档数据,需要 基于字符串的操作,例如匹配(包括正则表达式)、索引、搜索、排序 等。

用户,尤其是实现者,有时会对相似字符串是否匹配 或不匹配,以及可能应用于文本的不同转换的有效性抱有过于简单的预期,尤其是在 句法内容方面,但也包括 Web 上的许多文本处理类型。

由于 Web 从根本上对文本在文档中的不同表示方式很敏感, 未考虑同一文本的不同表示方式,可能会使 用户困惑,或导致意外或令人沮丧的结果。在以下章节中,本文档考察了 影响用户对 Web 文本的感知以及 Web 所依赖的字符串处理的不同 文本变化类型。

2.1 大小写映射与大小写折叠

某些文字和书写系统区分大写、小写和标题大小写字符。大多数 文字,包括印度婆罗米系文字、阿拉伯文字以及用于书写 中文、日文或韩文的文字,都不区分大小写,但某些重要文字区分大小写。 这类文字包括本文档大部分内容使用的拉丁文字,以及 希腊文、亚美尼亚文和西里尔文等文字。

大小写映射是 将字符转换为特定大小写(例如大写、小写或标题大小写)的过程。对于 区分大小写的文字,Unicode 为每个 Unicode 码位定义了默认的大写、小写和标题大小写 字符映射。大小写映射起初看似简单,但在以不同语言处理完整 Unicode 范围时, 还需要考虑各种变化。

大小写 折叠是为了比较目的,将仅大小写不同的两段文本转换为相同文本的过程, 即它用于字符串匹配。这与大小写映射不同,后者主要用于显示目的。与 默认大小写映射一样,Unicode 为每个 Unicode 码位定义了默认大小写折叠映射(“大小写折叠”)。Unicode 定义了两种大小写折叠形式,下面将对其进行说明。

由于大多数文字不区分大小写,因此与大小写映射一样,大多数 Unicode 码位不 需要大小写折叠。对于具有大小写折叠的码位, 大多数都具有简单、直接的映射,可映射到另一个匹配的单个 (通常为小写)码位。Unicode 将这组折叠称为 common,因为 Unicode 定义的两种大小写折叠都 包含这些映射。

少数字符具有从一个 Unicode 码位映射到两个或更多码位的大小写折叠。这组 大小写折叠称为 full 大小写折叠。fullcommon 大小写折叠结合使用,为 整个 Unicode 提供默认大小写折叠。在本文档中,我们将这种大小写折叠形式称为完整 大小写折叠Unicode 完整折叠

由于某些应用程序在执行大小写折叠操作时无法分配额外存储空间, Unicode 提供了 simple 大小写折叠,它会将通常 折叠为更多或更少码位的码位,改为映射到单个码位以供比较。 与完整折叠不同,这种折叠总会改变文本的内容(并可能改变其含义)。 与完整大小写折叠一样,简单 大小写折叠Unicode 简单折叠,是 simplecommon 映射的组合,从而覆盖 Unicode 的完整范围。 Unicode 简单折叠不适合在 Web 上使用。

请注意,大小写折叠会从字符串中移除以后无法恢复的信息。例如, 德语文本中的两个 s 字母,在未折叠文本中不一定表示 ß

2.1.1 语言敏感性

大小写映射和大小写折叠的另一个方面,是它们可能对语言敏感。 Unicode 为每个编码字符定义了默认大小写映射和大小写折叠,但 这些只是默认值,并非在所有情况下都适用。某些 语言需要定制大小写映射,以满足特定的语言学 需求。一个示例是使用拉丁文字书写的 突厥语族语言:

虽然上面的示例(以及本文档总体上)侧重用于 匹配的大小写折叠,但请注意,大小写映射也与语言相关。土耳其第二大城市的名称是 “Diyarbakır”,其中 同时包含带点和不带点的字母 i

2.1.2 大小写折叠的用途

某些文档格式或协议会通过忽略其所定义词汇表中 或格式或协议所允许的用户提供的值中的大小写变化,来促进互操作性或帮助内容作者。

有时,大小写可能以语义上没有意义 或不完全受用户控制的方式变化。这在 搜索文档时尤其常见,但有时也可能适用于 定义用户或内容生成值(例如标识符)的匹配规则。 在这些情况下,可能更适合使用不区分 大小写的匹配。

定义词汇表时,一个重要考虑因素是这些值 是否仅限于 Unicode 的 ASCII [ASCII] 子集,或者该词汇表是否允许使用可能具有更复杂大小写折叠要求的字符 (例如拉丁字母上的重音符号,或包括非拉丁文字在内的广泛 Unicode 范围)。 为满足这些不同要求,本文档针对文档格式或协议中的字符串同一性匹配, 定义了四种大小写折叠匹配类型:

区分 大小写的匹配:直接比较码位,不执行大小写折叠。

ASCII 不区分大小写的匹配在 [INFRA] 中进行了定义。该定义比较两个码位 序列,就好像范围 0x41 至 0x5A(A 至 Z)内的所有 ASCII 码位都已映射到 范围 0x61 至 0x7A(a 至 z)内的对应码位一样。当词汇表本身受限于 ASCII 时,可能要求使用 ASCII 不区分大小写的匹配。

Unicode 不区分大小写的匹配比较两个码位序列,就好像已经对 两个输入序列应用了Unicode 完整大小写折叠(见上文)一样。

语言敏感的 区分大小写匹配适用于少数情况,即文档格式或协议 包含有关句法内容语言的信息,并且可以合理应用语言敏感的大小写 折叠。这些大小写折叠定义在 Unicode 联盟的通用区域设置数据 存储库 [UAX35]项目中。

有关如何处理大小写折叠的建议,请参阅3.2.6 大小写折叠的其他注意事项

2.2 Unicode 规范化

Unicode 文本中可能出现另一种变化:有时可以使用多个不同的Unicode 码位序列来表示同一个 抽象字符。通过比较码位搜索或匹配文本时,这些编码变化会导致用户认为相同的 文本值无法匹配。

由于应用程序需要在使用不同码位序列的文本中找出语义等价性, Unicode 定义了一种使两个语义等价文本变为相同文本的方法:Unicode 规范化形式 [UAX15]。

资源通常容易受到这些变化的影响, 因为 Web 上的规范和实现并不要求对文本执行 Unicode 规范化, 也没有考虑之后在处理句法内容(包括用户提供的值)和可本地化内容时使用的字符串匹配算法。因此,内容 开发者需要确保提供一致的表示形式,以避免以后出现 问题。

但是,用户可能难以确保给定资源 或资源集合使用一致的文本表示形式,因为 这些差异在作为文本查看时通常不可见。因此,工具和 实现需要考虑用户面临的困难:在用户看来“应该” 匹配的视觉或逻辑等价字符串,却被视为不同值。 为用户提供查看这些差异和/或根据需要对其进行规范化的 方法,使最终用户能够避免因源文档中不可见差异 导致的失败。例如,当 HTML 文档未完全采用 Unicode 规范化形式 C 时,W3C 验证器会发出警告。

2.2.1 规范等价与 兼容等价

Unicode 定义了字符之间的两种等价类型:规范等价兼容等价

规范 等价是表示相同抽象字符的 Unicode 码位或 Unicode 码位序列之间的 基本等价关系。规范等价的序列 理想情况下应具有相同的视觉外观(尽管有许多因素可能导致它们 看起来略有不同),并且应将其视为相同内容进行处理。 Unicode 定义了一个称为规范分解的过程,用于消除两个编码不同但规范等价文本之间的这些 主要差异。

Unicode 定义的规范等价示例包括:

  • Ç 预组合序列与组合 序列。某些字符可由一个基本 字符后跟一个或多个组合字符构成。同样的 字符有时也会被编码为单独的“预组合” 字符。在此示例中,字符 Ç [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] 与希腊字母 Omega Ω [U+03A9 GREEK CAPITAL LETTER OMEGA] 规范等价(且外观相同)。(另一个单元素映射示例是上述编码变化示例中的 [U+212B ANGSTROM SIGN]
  • 가 韩文。韩文用于 书写韩语。该文字按逻辑方式构造, 每个音节都是一个大致呈方形的字素, 由表示辅音和 元音的特定子部分构成。这些特定子部分称为字母,并 编码在 Unicode 中。预组合音节也同样如此。因此, 音节 [U+AC00 [Hangul Syllable, First]] 与其组成的 字母字符 가 [U+1100 HANGUL CHOSEONG KIYEOK + U+1161 HANGUL JUNGSEONG A] 规范等价。

兼容等价是表示 相同抽象字符,但可能具有不同视觉外观 或行为的 Unicode 字符或 Unicode 字符序列之间的一种较弱等价关系。通常,称为兼容分解的过程会移除 上标、下标、旋转、 带圈等格式变化,但也存在其他变化。在许多 情况下,具有兼容分解的字符表示一种 语义区别;因此,用其兼容分解替换不同字符可能会 改变文本含义。兼容分解后等价的文本 在此前通常不会被视为相同内容,形式语言不应将其视为等价。

在上表中,需要特别注意的是,所示字符是实际的 Unicode 码位, 而不仅仅是上下文或样式导致的呈现 变化。每个字符都是为了与各种旧式字符 编码兼容而编码进 Unicode 的。不应将它们与 对非兼容对应字符进行的普通呈现 处理相混淆。

例如,大多数阿拉伯文字文本使用 Unicode 阿拉伯文字块 (从 U+0600 开始)中的字符。用于显示 文本的实际字形,是根据字符在单词中的位置 (开头、中间、结尾或独立)使用字体和文本处理逻辑选择的, 此过程称为“塑形”。上表显示了阿拉伯字母 ه [U+0647 ARABIC LETTER HEH] 的四种 呈现形式。所示字符是 U+FE00 块中的兼容字符, 每个字符都表示一种特定的“位置”形状,并且所示四个码位都具有到 普通阿拉伯字母 ه [U+0647 ARABIC LETTER HEH] 的兼容分解。这些呈现形式仅用于支持与包含等价呈现形式的旧式字符编码 之间的往返编码转换。否则,包含一系列字母 “heh”的字符串只会编码为一系列 U+0647 码位, 由呈现系统和字体提供适当的形状。

同样,半角和全角形式以及旋转 字符(用于垂直文本)的变化,也主要为了与旧式字符编码兼容而 编码为单独码位。在 许多情况下,这些变化与东亚宽度 [UAX11]中描述的 Unicode 属性相关。 有关垂直文本呈现形式的讨论,另请参阅Unicode 垂直文本布局 [UAX50]。

对于具有兼容分解的字符,例如 上面所示字符,K Unicode 规范化形式会将文本转换为“普通”或“预期”的 Unicode 码位。但是,不能根据这些兼容 字符的存在,推断正常文本布局和 呈现过程中产生的类似外观变化会受到 Unicode 规范化影响。它们不会受到影响。

2.2.2 组合与 分解

Unicode 定义的这两种等价类型,又根据另一对变化进行分组: “分解”和“组合”。在“分解”中,视觉字符中可分离的逻辑部分 会拆分为基本字符和组合标记序列,并将所得码位 放入固定的规范顺序中。在“组合”中,先执行分解,然后 根据特定规则将组合标记与其基本字符重新组合。

警告

粗略地说,NFC 的定义方式,是尽可能将每个 组合字符序列(一个基本字符后跟一个或多个组合字符) 替换为规范等价的预组合字符。

非常重要的一点是,要注意这并不意味着什么。所得 字符序列仍可能包含组合标记,因为并非所有字符序列都有 预组合等价形式。事实上,正如我们所看到的,许多文字没有其他方式,只能 使用组合标记,例如此 示例中的天城文元音。在其他情况下,给定的基本字符和组合标记不会被 预组合字符替换,因为该组合受到规范化规则阻止。例如, 由于组合排除规则,某些印度文字不会组合某些基本字符加附加符号的序列, 即使存在匹配的预组合字符。 两个原本可以组合的字符之间如果存在另一个组合标记, 也可能阻止组合。

2.2.3 Unicode 规范化 形式

Unicode 规范化形式共有四种。每种形式都使用字母代码命名:

  • D(或 NFD)表示规范分解
  • C(或 NFC)表示 组合,即先进行规范分解,再进行组合。
  • KD(或 NFKD)表示兼容分解(使用 K 是因为 字母 C 已被占用)。
  • KC(或 NFKC)表示先进行兼容分解,再进行组合。

Unicode 规范化将这些序列(以及表示相同字符的其他潜在转义 序列)减少为仅三种可能的 变化。但是,Unicode 规范化不会消除所有 文本差异,并且在给定上下文中,应用 Unicode 规范化有时会移除具有区别作用或有意义的内容。例如:

  • 并非所有兼容字符都具有兼容 分解。
  • 某些外观相似或语义相近的字符,在 Unicode 中实际上是不同字符, 并且没有将它们联系在一起的规范分解或兼容分解。例如, [U+3002 IDEOGRAPHIC FULL STOP] 在中文或日文等语言中用作句末 句号。但是,它不被视为与 ASCII 句号字符 . [U+002E FULL STOP] 等价。
  • 某些字符变化不由 Unicode 规范化形式处理。例如,大写、标题大小写和小写 变化是另一种独立的文本变化,在比较文本时必须 单独处理。
  • 兼容规范化会移除含义。例如,字符序列 (其中包括字符 ½ [U+00BD VULGAR FRACTION ONE HALF]), 使用一种兼容规范化形式 (即 NFKDNFKC)进行规范化后,会变成 ASCII 字符序列: 81/2

2.3 外观相同的字符与规范化的局限性

许多用户会惊讶地发现,两个外观相同的字符串——包括 已应用特定 Unicode 规范化形式的字符串——实际上可能 并未使用相同的底层Unicode 码位。这包括 已应用破坏性更强的 NFKCNFKD 兼容规范化 形式的字符串。即使字符串、标记或标识符在视觉上看起来相同, 它们也可能采用不同编码。

Unicode 规范规范化形式关注的是,将可用于表示给定抽象字符或字素簇的多个不同码位 序列折叠为相同的码位 序列。但是,逻辑上不同的字符或字素簇仍可能看起来相同或非常 相似。当一对字素看起来相同(或非常相似)时,称为同形异义字。当一对字素看起来相似或属于同形异义字,但实际上表示逻辑上不同的字符或 字符序列时,称其为易混淆字符

即使在同一种文字中,也可能出现外观相同或看似相同的字符。这可能 表现为形状相似的字符,例如“0”和“O”或“l”和“1”。但其他文字或 不同兼容字符的使用,可能带来更难区分的变化。在 某些情况下,Unicode 规范化会将这些字符统一起来,但在许多其他情况下不会。

外观相同或易混淆的字符可能带来欺骗和 其他安全风险。这种情况既可能发生在同一种文字中,也可能发生在不同文字的相似字符之间。 有关同形字形和易混淆性的进一步讨论和示例, 一个有用的参考是 [UTS39]。

除了外观相同或相似的字符外,还存在相反的问题: Unicode 规范化,即使是 NFKCNFKD 兼容形式, 也不会统一具有相同内在含义或功能、 但外观或用法不同的字符。例如,U+002E(.) 和 U+3002(。)都用作句末标点, 但规范化不会消除这种差异,因为这些字符具有不同的身份。

2.4 规范化与 大小写折叠的相互作用

以不区分大小写的方式匹配字符串时,一个复杂之处在于,即使原始字符串已规范化, 大小写折叠过程也可能 产生未规范化的字符串。由于字符串 比较依赖于匹配码位序列,如果要保证匹配过程可靠, 则必须对每个经过大小写折叠的字符串进行规范化。

Unicode 规范规范化形式(NFC 或 NFD)和大小写 折叠结合使用时具有闭包性:一旦字符串经过大小写折叠并应用 NFD 或 NFC,再次应用相同的大小写折叠 或 Unicode 规范化形式都不会产生不同的字符串。

比较字符之间的兼容等价 (换言之,NFKC/NFKD 形式)时,必须执行两次大小写折叠和规范化操作, 因为兼容分解步骤可能产生需要大小写折叠的字符, 而随后执行的大小写折叠又可能产生必须再次规范化的序列。

2.4.1 为什么 规范化先于大小写折叠?

Unicode 对规范大小写折叠匹配(规则 [D145])和 兼容大小写折叠匹配(规则 [D146])的定义包括多个 规范化步骤。这增加了执行无大小写匹配的复杂性和成本。在执行大小写折叠之前的 初始规范化步骤,用于处理本节详细说明的特定边缘情况。

Unicode 大小写折叠匹配过程中的最后一个规范化步骤,用于确保 所得字符串采用特定的 Unicode 规范化形式。如果所得大小写折叠字符串 要存储或显示给用户,确保大小写折叠操作产生的未规范化 序列重新规范化以供显示,是一种良好实践。但是,由于额外执行规范化 不会改变字符串比较结果,因此此步骤在Unicode 规范 大小写折叠规范化步骤Unicode 兼容大小写折叠规范化步骤中是可选的。

六十三个希腊文预组合字符具有包含字符    ͅ [U+0345 COMBINING GREEK YPOGEGRAMMENI] 的分解映射(即规范化为 NFD 形式),该字符是表示下标 iota 的附加符号 (称为 prosgegrammeiypogegrammeni)。此标记表示古希腊语或古典 希腊语中的一种正字法形式,对应的声音在更现代的语言形式中已不存在。这些字符的大写和标题大小写 映射会将此组合标记分离为单独的基本字母 iota。为了与标题大小写/大写映射保持一致,这些 字符的大小写折叠映射因此包含 ι [U+03B9 GREEK SMALL LETTER IOTA]回顾一下,Unicode 大小写折叠通常折叠为小写)。

当且仅当这 63 个字符中的某个字符后跟组合标记时, 未在大小写折叠前应用规范分解,可能导致潜在的比较不匹配。此类字符 序列不处于规范化形式,并且很难通过键盘 和其他输入过程“自然”生成。

例如,如果从预组合(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,会产生与上面第一个 示例相同的字符序列:

在这两种情况下,锐音符号都与 alpha 基本字符相关联,而不是与 后面的 iota 相关联。

但是,如果从半预组合序列 ᾌ [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],其中锐音符号与 iota 相关联。 这会产生一个无法规范化为与其他序列匹配的序列(并且实际上是不正确的,因为 它与原始用户感知字符具有不同含义)。

如上所述,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 中编码为十六进制 实体 &#x20ac;,或十进制实体 &#8364;。 在 JavaScript 或 JSON 文件中,它可以表示为 \u20ac\u{20AC}, 而在 CSS 样式表中可以表示为 \20ac。所有这些 表示形式都编码了相同的字面字符值:

字符转义通常在处理文档和匹配格式或协议中的字符串之前进行解释。 回到上面使用过的示例:

您会预期该文本显示如下:Hello world!

为了使其正常工作,用户代理(浏览器)必须匹配表示类名 héllo 的两个字符串,即使 CSS 和 HTML 各自使用了不同的转义机制。上述 片段展示了文本可以发生变化但仍依据规范被视为“相同”的一种方式: 类名 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 Joiner(也称为 ZWJ)和 U+200C Zero Width Non-Joiner(也称为 ZWNJ)。 虽然这些字符可以用于控制连字形成——防止形成不需要的 连字或促进形成所需连字——但它们的主要用途是控制 阿拉伯文或各种印度文字等复杂文字中的连接和形状选择。 某些印度文字使用 ZWJ 和 ZWNJ 字符,允许作者控制某些 合字采用的形状。请参阅 [Unicode] 第 12 章中的 讨论。

Zero Width Non-Joiner 在波斯语中用于 阻止某些“正常”的阿拉伯文字连接。在这些情况下,字符存在或缺失 确实会影响含义。例如,单词 تنها(“单独”)和单词 تن‌ها (“身体” 或“语料”)分别编码为“U+062A U+0646 U+0647 U+0627”和“U+062A U+0646 U+200C U+0647 U+0627”, 唯一区别是后一个单词中存在 ZWNJ。

ZWJ 字符还用于形成某些表情符号序列,下面将进行更 详细的讨论。

变体选择符(U+FE00U+FE0F)是 用于选择替代外观或字形的字符 (请参阅《字符模型:基础》[CHARMOD])。例如, 它们用于在黑白表情符号和彩色表情符号之间进行选择。 它们还用于预定义的表意文字变体序列(IVS)。Unicode 字符数据库(UCD)的 “标准化变体”部分提供了许多示例。

少数文字还提供编码视觉变体选择的方式:一个突出的示例 是蒙古文的自由变体选择符(U+180BU+180D)。

字符 U+034F Combining Grapheme Joiner 的名称容易引起误解(因为它不会连接字素),它用于分隔 在排序时可能被视为一个字素的字符,或提供一种 在对文本应用 Unicode 规范化时保留某些文本差异的方法。

空白字符变化也可能影响文本的解释和 匹配。例如,各种不换行空格 字符,如 NBSP、NNBSP 等。

U+200B Zero Width Space 是一种用于 指示原本没有空格的文本中单词边界的字符。 例如,它可能用于泰语文档以辅助 断词。

U+00AD Soft Hyphen 可用于文本中指示 潜在或首选的断字位置。只有当文本重新排版并在该位置换行时, 它才会可见。

U+2060 WORD JOINER 有时称为 WJ,是一种 零宽不换行空格字符。其用途是防止两个字符之间换行。 除换行用途外,应忽略该字符。它用作字符 U+FEFF ZERO WIDTH NO-BREAK SPACE 的替代字符,因为 U+FEFF 更常被称为“字节顺序标记”(BOM)。字节顺序 标记用于某些纯文本文件开头,以表明该文件采用 Unicode 字符 编码。

最后,大多数文字在水平书写时从左向右排列。但是,某些文字(例如 阿拉伯文和希伯来文)主要从右向左书写。文本中可能混合使用 这些文字,或者包含数字或另一种文字中的引号等字符序列, 其方向与文本其他部分相反。这种文本方向的混合称为 双向文本,简称bidi。Unicode 双向算法 [UAX9]描述如何处理此类混合方向文本 以供显示。对于大多数文本,可以从文本本身推导方向处理方式。 但是,在许多情况下,该算法需要额外信息才能正确呈现 文本。有关更多示例,请参阅 [html-bidi]。

Unicode 为解决文本方向歧义而定义的一种方式,是使用一组不可见 控制字符来 标记方向行程的开始和结束。虽然双向控制字符可能影响文本 外观(因为它们帮助 Unicode 双向算法呈现文本),但如果文本本身在没有这些控制字符时 自然形成相同的双向行程,它们也可能不会对文本产生任何 影响。由于这些 控制字符与上述字符一样不可见,因此可能会对匹配产生非预期 影响。

在几乎所有这些情况下,用户可能不知道或无法 确定给定文档或文本字符串是否包含或省略了其中 某个字符。由于文本匹配依赖于匹配 底层码位,这些标记导致的文本编码变化, 可能使本应成功的匹配从用户角度看莫名其妙地 失败。

2.7 表情符号序列

Unicode 较新的功能之一是表情符号字符。在 [UTS51] 中,Unicode 对其描述如下:

表情符号是通常以彩色卡通 形式呈现,并在文本中以内联方式使用的象形图(图形符号)。它们表示面孔、天气、车辆和建筑、 食物和饮料、动物和植物等事物,或表示情绪、感受或活动的图标。

表情符号可以与各种表情符号修饰符一起使用,包括 U+200D ZERO WIDTH JOINERZWJ, 从而形成更复杂的表情符号。

例如,表情符号(👪 [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 会在支持此类 组合的系统上生成“家庭:男人、女人、女孩、女孩”的组合 表情符号。许多常见表情符号只能使用 ZWJ 序列构成。有关更多 信息,请参阅 [UTS51]。

表情符号字符后面可以跟随表情符号修饰符字符。这些修饰符允许为表示人物的表情符号 选择肤色。这些字符通常是不可见修饰符, 位于其所修饰的基本表情符号之后。例如: 👨 👨🏻 👨🏼 👨🏽 👨🏾 👨🏿

表情符号字符后还可以跟随变体 选择符,以指示基本表情符号采用文本形式(黑白,由 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):🇿🇲。其他区域或特殊用途旗帜可 使用旗帜表情符号与各种符号构成,或使用以 取消标签结尾的区域指示符代码。例如,苏格兰旗帜(🏴󠁧󠁢󠁳󠁣󠁴󠁿)可以这样构成:

这些机制可以一起使用,因此可以使用非常复杂的字符序列 构成单个表情符号字素或图像。即使非常相似的表情符号序列,也可能不使用完全相同的 编码序列。在大多数情况下,上述修饰符和组合由 最终用户的键盘生成(键盘将其呈现为单个表情符号“字符”)。这种编码 选项的多样性,在一定程度上通过不同供应商仅使用(并精确使用)Unicode “建议用于交换”的序列来解决。这有助于供应商确保字体和键盘 准备好为用户提供预期选项。不过,用户通常不会意识到 底层编码的复杂性,并且生成机制不限于建议的机制。 表情符号序列发展迅速,因此近期可能还会出现有助于或阻碍 表情符号匹配的新发展。Unicode 规范化不会重新排序这些序列,也不会插入 或移除任何修饰符。因此,应提醒用户和实现者:在命名空间和其他匹配上下文中 使用表情符号字符的用户,很容易因编码变化遇到意外的“字符” 不匹配。

2.8 旧式字符编码

资源可以使用不同的字符编码 方案(包括旧式字符编码)来序列化 Web 上的文档格式。每种字符编码方案使用 不同的字节值和序列来表示通用字符集的给定 子集。

强烈建议所有文档、格式和 协议选择 Unicode 字符编码(例如 UTF-8),因为使用旧式字符编码不会获得 任何额外效用,并且可以完全避免本节其余部分所述 注意事项。

例如, [U+20AC EURO SIGN]UTF-8 字符编码中 编码为字节序列 0xE2.82.AC。同一个 字符在旧式字符编码 windows-1252 中 编码为字节序列 0x80。 (其他旧式字符编码可能没有任何可用于 编码该字符的字节序列。)

规范主要通过以下方式处理这些产生的变化: 将每个文档视为从该文档字符编码 (无论是旧式字符编码,还是 UTF-8 等 Unicode 编码)转换后得到的 Unicode 字符序列, 然后在继续处理文档之前 展开所有字符转义。

即使在单一旧式字符编码内部,实现也可能存在 差异。一个著名示例是旧式 日文编码 Shift_JIS。不同的 转码器实现在如何将特定 字节序列映射到 Unicode 时面临不同选择。因此,字节序列 0x80.60 (JIS X 0208 字符集中的 0x2141)被 某些实现映射到 U+301C WAVE DASH,而其他实现选择 U+FF5E FULL WIDTH TILDE。这意味着两个合理且 内部一致的转码器,可能从相同输入产生不同的 Unicode 字符 序列。Encoding [Encoding] 规范存在的部分原因,是确保 Web 实现使用 可互操作且完全相同的映射。但是,不能保证 与 Encoding 规范一致的转码器会被应用于 Web 上发现的文档,或用于处理 特定文档格式或协议中出现的数据。

转换到 Unicode 时的另一个注意事项,是双向文字 (例如希伯来文和阿拉伯文)的旧式字符编码可能采用 视觉存储顺序。也就是说,与 Unicode 和其他现代编码不同, 字符在内存中按其从左向右打印到屏幕上的顺序存储 (类似行式打印机)。将这些编码转换为 Unicode, 或比较这些编码中的文本时,必须注意将源文本和目标文本都置于逻辑顺序中。 有关更多信息,请参阅 [CHARMOD] 第 3.3.1 节。

2.9 其他等价类型

执行自然语言搜索或“查找”功能时,还有其他适用的等价或处理 类型。字符模型系列文档的另一部分对此进行了说明([STRING-SEARCH])。 为词汇表制定的规范,或定义用于 形式语法的匹配算法的规范,应该避免尝试应用该文档所述的额外自定义折叠、 映射或处理,因为这些操作会妨碍产生 一致且可预测的结果。

3. 文档格式和协议中句法内容的字符串匹配

在 Web 环境中,字符串可以使用不同的字符编码,在这些编码中使用不同的字符 序列,并具有本文档所述的其他变化(例如大小写),因此建立一种一致的字符串同一性 评估过程非常重要。

本章定义了在句法 内容中规定和实现字符串匹配的要求。

3.1 指定内容 限制

提高字符串匹配有效性和一致性的一种方法,是对要匹配的内容应用 限制。词汇表的定义,尤其是 允许在其中使用用户提供的值的词汇表,必然 包括构成“有效标识符”的规则。这通常包括长度和内容 限制。定义这些限制的一些最佳实践包括:

§

规范不应允许标识符中包含代理码位 (U+D800U+DFFF)或非字符码 位。

§

规范不应允许标识符中包含 C0U+0000U+001F)和 C1U+0080U+009F)控制字符。

标识符大致分为两类:面向用户的标识符应用程序内部标识符

应用程序内部标识符是文档格式或协议 词汇表中可由机器读取且不用于 显示的部分。为了方便需要处理或调试文档格式或协议内容的开发者 或内容作者,通常会为这些标识符指定有意义的名称(一般使用英语)。

§

定义应用程序内部标识符(这些标识符 从不向用户显示,并且始终用于应用程序或 协议内部的匹配或处理)的规范,应该将内容限制为 ASCII 的可打印子集。建议使用ASCII 不区分大小写的匹配

§

向最终用户显示应用程序内部 标识符字段或值时,必须使用可本地化的 显示值将其包装起来。

面向用户的标识符是文档 格式或协议词汇表中由用户分配或编辑,或者提供给 用户选择的部分。面向用户的标识符示例包括网络名称(例如 SSID)、 设备名称、类名、样式名或属性名,以及用户定义的设置或值。由于本文档所述 问题,这类标识符的匹配更为复杂,但它们能提供最佳 体验,尤其是对于不会说英语或不熟悉拉丁 文字的用户。

许多面向用户的标识符也是用户提供的值,可以由文档格式或协议的 用户分配。允许使用用户或其社区或文化偏好的自然语言, 可以提供更出色的用户体验,并让语言能力有限的受众更容易使用相关功能, 尤其是英语能力有限的受众。

§

当标识符对用户可见或可能可见时,规范应该允许使用非 ASCII Unicode 字符,以确保 使用各种语言的用户都能平等访问所产生的文档格式或协议。 建议区分大小写(即不执行大小写折叠)。

虽然应该允许广泛的 Unicode 字符,但规范仍可以对面向用户的标识符内容施加某些 实际限制。定义此类内容规则的规范示例,可在Unicode 标识符和模式语法 [UAX31]中找到。

3.2 选择匹配算法

为给定规范选择匹配算法时,基本决定是应对所匹配的字符串应用何种程度的 文本规范化(包括大小写敏感性和 Unicode 规范化)。从历史上看,Web 上的大多数规范 选择了区分大小写且不执行 Unicode 规范化的匹配,这也是所有新规范建议采用的 匹配形式。但是,在某些情况下,不区分大小写和规范化是有用的。

当相关格式或协议为用户带来的好处超过实现成本和复杂性时,规范可以选择 不区分大小写。由于大小写折叠和规范化都会影响所比较的值,包括文本的呈现, 并且在某些情况下会影响文本含义,同时这些操作的开销相对较高,因此通常不鼓励选择 不区分大小写。

不区分大小写的一种特殊情况,是词汇表仅限于 ASCII/基本拉丁字符范围(即 码位 U+0000U+007F)。这些 规范可以选择仅在该字符范围内不区分大小写。这会极大 简化匹配的实现。但是,这种匹配形式不适用于 允许标识符或语法中使用更大 Unicode 范围的规范,因为用户难以 理解这种匹配行为,并且会对非 ASCII 文字和语言的用户造成不利影响。 也就是说,当 greenGREEN 匹配, 但 grüß 不与 GRÜẞ 或可能的 GRÜSS 匹配(而是与 GRüß 匹配)时,用户会觉得这种行为怪异且不可预测。

3.2.1 匹配算法

匹配算法描述了比较两个字符串所需的一系列步骤。

  1. 将要比较的字符串转换为 Unicode 码位序列。这可能需要从旧式字符编码进行转码
  2. 展开所有字符转义和包含
  3. 执行适当的规范化步骤
  4. 执行规范特有的任何其他匹配定制
  5. 比较所得码位序列是否相同。

3.2.2 执行适当的规范化步骤

适用于给定规范的文本规范化方式,取决于格式或 协议词汇表中的要求。文本规范化有四种选择:

  1. 默认。此规范化步骤对文本没有影响,因此 对大小写和 Unicode 规范化形式方面的差异都敏感。
  2. ASCII 大小写折叠。比较时,对 ASCII (基本拉丁字符,U+0000U+007F) 范围内的字符执行大小写折叠。
  3. Unicode 规范大小写折叠。比较既执行了大小写折叠, 又应用了 Unicode 规范规范化的文本。
  4. Unicode 兼容大小写折叠。比较既执行了大小写折叠, 又应用了 Unicode 兼容规范化的文本。
3.2.2.1 默认 规范化步骤
§

在匹配标识符和句法内容中的字符串时,建议不执行 任何大小写折叠或 Unicode 规范化。

此规范化步骤对文本没有影响,因此比较会对 所比较源字符串中的大小写差异和 Unicode 规范化形式差异都敏感。 如果内容作者希望标记能够匹配,就需要意识到这些差异,并确保使用一致的大小写和一致的 字符序列来编码受影响的文本。

3.2.2.2 ASCII 大小写 折叠规范化步骤
§

“ASCII 大小写 折叠”方法仅应在特殊情况下使用,即词汇表本身 仅限于 ASCII 范围(或仅对 ASCII 标记执行匹配)时使用。

ASCII 大小写折叠规范化步骤仅对 ASCII 范围执行大小写折叠。不应用任何 Unicode 规范化形式。此步骤仅适用于词汇表本身 仅限于 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.2.2.3 Unicode 规范大小写折叠规范化步骤
§

对于大多数规范,不建议采用不区分大小写的匹配;但是,如果 词汇表允许非 ASCII 字符,并且不希望区分大小写,则属于例外情况, 应该使用“Unicode 规范大小写折叠”方法。

允许非 ASCII 字符的词汇表,应该包括大多数新词汇表。

Unicode 大小写折叠可能产生未规范化的字符序列,因此,为了使匹配符合 用户预期,任何 Unicode 大小写折叠之后都需要执行 Unicode 规范化。有关示例,请参阅2.4 规范化与大小写折叠的相互作用

[Unicode] 要求 D145 在大小写折叠操作之后执行规范化步骤,以确保所得 字符串处于规范化形式。大小写折叠后的规范化步骤是可选的。如果所得字符串仅用于比较, 而不存储或向用户显示,则大小写折叠后的码位序列是等价的。 只是不能保证它们处于任何特定的规范化形式。这是对 D145 的故意违反。 Unicode 已确认这是一项有效的建议。

对每个字符串执行以下步骤:

  1. 对字符串执行 Unicode 规范化,将其转换为 NFD 形式 NFC 形式。
  2. 对所得字符串执行Unicode 完整大小写折叠。
  3. [可选] 对所得字符串执行 Unicode 规范化, 将其转换为 NFC。这可以确保 字符串处于适合向用户显示的规范化形式。
  4. 返回结果。
3.2.2.4 Unicode 兼容大小写折叠规范化步骤

具有允许非 ASCII 字符的词汇表,并且需要匹配 Unicode 兼容等价形式的规范,可以使用此规范化步骤。由于兼容 规范化形式(NFKCNFKD)会改变文本的含义、外观和 处理方式,因此大多数 Web 应用程序不应使用此步骤。

警告

大小写折叠会受到输入码位序列的影响。它也可能产生未规范化的 码位序列。兼容分解与大小写折叠之间的交互,需要 多次处理才能产生一致的匹配。因此,此规范化步骤包括 多次使用 Unicode 规范化。有关示例,请参阅2.4 规范化与大小写 折叠的相互作用

对每个字符串执行以下步骤:

  1. 对字符串执行 Unicode 规范化,将其转换为 NFD 形式,执行 对受影响的 63 个希腊字符的映射。
  2. 对所得字符串执行Unicode 完整大小写折叠。
  3. 对所得字符串执行 Unicode 规范化,将其转换为 NFKD。
  4. 对所得字符串执行Unicode 完整大小写折叠。 (这会消除兼容映射产生的残留结果。)
  5. [可选] 对所得字符串执行 Unicode 规范化, 将其转换为 NFKC。(这可以确保码位序列经过规范化, 适合显示。)
  6. 返回结果。

3.2.3 转换为 Unicode 码位序列

§

内容作者应该使用 Unicode 字符编码输入和存储资源 (Web 上通常使用 UTF-8)。

比较文本的第一步,是确保两者使用相同的数字表示形式。这 意味着实现需要将采用旧式 字符编码的任何文本转换为 Unicode 码位序列。通常通过应用 转码器,将数据转换为一致的 Unicode 编码形式(例如 UTF-8 或 UTF-16)。这样就可以对字符串进行按位比较,以 确定字符串是否相等。

§

内容作者在将旧式编码的文本或资源转换为 Unicode 时,应该选择 规范化转码器,除非特定字符的映射会干扰 含义。

规范化转码器是一种转码器,它 从旧式字符编码 转换为 Unicode,并且确保结果处于 Unicode 规范化形式 C(NFC)。对于大多数旧式字符编码,可以 构造规范化转码器(方法是在任意转码器之后使用规范化器);如果旧式字符 编码字符集合中包含 Unicode 未表示的字符,则无法构造此类转码器。虽然规范化转码器仅产生 处于 NFC 的字符序列,但转换后的字符 序列可能不是包含规范化的(例如,如果它以 组合标记开头)。

由于 Web 上的文档格式通常会与其他外部 资源交互或使用这些资源进行处理(例如,将 CSS 样式表应用于 HTML 文档),因此在使用不同 字符编码的文档之间匹配值时,一致的文本表示形式非常重要。使用规范化转码器, 可以使旧式编码文档与大多数语言通常预期的 Unicode 字符序列匹配,从而帮助确保互操作性。

Web 上使用的大多数转码器会输出 NFC, 但也有一些不会。通常是为了使转码器能够与 源旧式字符编码进行往返兼容、保留其他字符差异,或与 用户代理中使用的其他转码器保持一致。这意味着 Encoding 规范 [Encoding] 和其他各种重要的转码 实现包含许多非规范化转码器。事实上,Unicode 中的大多数兼容 字符仅为从旧式编码进行往返转换而存在,其中许多字符在 NFC 中具有单元素规范映射。您在本文档前面的内容中已经见过使用 [U+212B ANGSTROM SIGN] 的示例。

请记住,大多数转码器都会产生 NFC 输出, 即使某些转码器不能为所有字符产生 NFC, 它们也会为绝大多数 字符产生 NFC。特别是,没有常用转码器会在存在预组合形式时 产生分解形式,或者产生与规范化序列不同的组合字符序列 (这对 [Encoding] 中的所有转码器都成立)。

§

规范必须允许使用 Unicode 字符 编码。

§

规范必须指定默认字符 编码,并且应该将 UTF-8 指定为默认编码。

§

规范应该禁止使用 UTF-8 以外的 编码。

旧式字符编码在 Web 上通常已经 失去作用。新规范需要从一开始就支持 Unicode 编码, 默认使用 Unicode 编码(通常为 UTF-8),并且在可能的情况下禁止使用任何 其他编码。这不仅能促进互操作性,还能减少字符和数据表示中 毫无意义的变化。

3.2.4 展开 字符转义与包含

大多数文档格式和协议都提供一种方法,将字符编码为转义序列,或者 将包括文本在内的外部数据包含到资源中。[CHARMOD] 第 4.6 节以及 上文对此进行了详细讨论。

执行匹配时,了解何时解释字符转义非常重要,以便 匹配能够适当地成功(或失败)。通常,转义、引用和包含会在执行匹配 (或对匹配敏感的处理)之前进行处理或展开,因为这些语法的存在 是为了便于将难以编码的 序列放入文档中,同时让字符的行为如同 直接以码位序列编码在相关文档中一样。

一个可能比较复杂的方面,是确定句法 内容可本地化内容如何交互。 例如,请考虑以下 HTML 代码片段:

虽然从技术上讲,组合标记  ̀ [U+0300 COMBINING GRAVE ACCENT​] 会与前面的 引号组合,但 HTML 不认为该字符(无论是否编码为实体)构成 HTML 语法的一部分。

对资源执行匹配操作时,一般规则是在用户正在交互的同一 “层级”展开转义。例如,在考虑上述示例时,用于 查看 HTML 源代码的工具会将转义序列 &#x300; 显示为以 & 符号开头的字符串。相比之下,JavaScript 程序操作的是浏览器对 文档的解释,并会将字符 U+0300 与属性 id 的值匹配。

处理文档格式的语法时,除非格式的处理规则明确禁止, 否则通常会在处理语法之前将转义转换为其所表示的字符 序列。这使资源能够在资源的句法结构中包含各种类型的字符。

在某些情况下,预处理转义会产生问题。例如,在解析 HTML 文档之前展开序列 &lt; 会产生文档错误。

3.2.5 规范化的其他注意事项

特定 Unicode 规范化形式并不总是适合内容作者或可供内容作者使用, 而且下游数据使用者可能无法了解用户选择的文本编码。如 本文档所示,内容作者或应用程序在输入或交换文本时,可以采用许多不同方式 表示相同的语义值。规范化可能会消除用户有意应用的差异。因此,匹配算法规定,仅在执行字符串大小写折叠匹配时使用 Unicode 规范化, 并且仅在算法内部使用。强制内容采用规范化形式可能会成为用户和实现者的障碍。因此:

§

规范不应为给定词汇表的编码、存储或交换 指定 Unicode 规范化形式。

§

实现不得更改正在交换、 读取、解析或处理的句法内容(包括用户提供的值)或可本地化内容的规范化形式, 除非文本转换的副作用要求这样做,例如将内容转码为 Unicode 字符编码、 执行大小写折叠或进行其他 用户发起的更改,因为使用者或内容本身可能依赖未规范化的 表示形式。

§

创作工具应该提供规范化 资源的方法,并在给定资源未采用 Unicode 规范化形式 C 时警告用户。

要求以特定规范化形式存储和交换文本的规范,需要处理3.2.5.1 在文档格式中指定规范化时的 要求

通常不鼓励规范要求格式或协议以规范化形式存储或交换 数据,除非存在要求这一附加条件的具体明确理由。由于 Web 上的许多文档格式不要求 规范化,内容作者有时可能依赖未规范化的字符序列。规范化步骤可能会对 此类内容产生负面影响。

规范规范化形式(NFC 或 NFD) 旨在保留所应用文本的含义和呈现方式。但情况并非总是如此, 这也是不建议规范化的原因之一。NFC 的优点是,几乎所有旧式数据(如果 以一对一的简单方式转码为 Unicode 编码),以及当前 软件创建的数据或用户在大多数(但不是所有)键盘上输入的数据,都已经处于这种形式。NFC 还具有轻微的紧凑性优势,并且在大多数语言中, 对于字符与字素之间的关系,更符合用户预期。

§

规范不应指定兼容 规范化形式(NFKC、NFKD)。

§

除非最终用户明确请求,否则实现不得应用兼容 规范化形式(NFKC、NFKD)。

兼容规范化形式(NFKC 和 NFKD)会以重要方式改变文本结构并丢失 文本含义。用户有时会有意使用在 Unicode 中具有兼容映射的字符, 或者使用旧式字符编码中在转换为 Unicode 时具有 兼容映射的字符。必须将其视为内容作者的有意选择。 虽然 NFKC/NFKD 有时可用于“查找”操作或搜索可本地化内容中的字符串, 但消除兼容差异是有害的。

要求使用 NFC,需要规范开发者格外谨慎, 因为 Web 上的内容通常不处于已知的 规范化状态。在这种情况下,需要仔细考虑并明确规定未规范化内容的边界和错误条件。

§

如果规范等价但彼此分离的 Unicode 字符序列构成 安全问题,规范必须记录该问题或提供 健康警告。

§

内容作者应尽可能为内容使用 Unicode 规范化形式 C(NFC)。

请注意,在某些语言中,NFC 并不总是适合相关内容, 甚至可能无法供内容作者使用。

§

内容作者应该始终使用 一致的 Unicode 字符序列对文本进行编码,以便匹配,即使格式或实现执行的匹配中 包含 Unicode 规范化形式。

为了使内容得到一致处理,内容作者应该尝试使用 一致的码位序列来表示相同文本。虽然内容可以采用任何 规范化形式,也可以使用未规范化(但有效)的 Unicode 字符序列, 但表示不一致会导致实现将不同序列视为 不同内容。确保一致选择、访问、提取、处理或显示的最佳方式, 是始终使用 NFC

§

内容作者不应在资源中包含前面没有基本字符的组合标记。

这可能存在例外。例如,制作字符列表(例如 [Unicode] 字符列表)时,作者可能希望使用 没有对应基本字符的组合标记。但是,在没有基本字符的情况下使用组合标记, 可能会导致非预期的显示或处理问题,例如当简单的 实现将组合标记与相邻的句法内容、用户提供的内容或可本地化 内容组合时。例如,如果使用组合标记(例如字符  ́ [U+0301 COMBINING ACUTE ACCENT​])作为 HTML 中 class 属性值的开头, 类名可能无法在编辑器中正确显示,并且难以编辑。

一些建议的基本字符包括 [U+25CC DOTTED CIRCLE](当基本字符需要 可见时)或   [U+00A0 NO-BREAK SPACE](当基本字符应该不可见时)。

由于内容作者并不总是遵循这些指南:

§

词汇表规范必须定义 句法内容与字符数据之间的边界,以及实体边界(如果该 语言具有任何包含机制)。这些边界需要包括语言实例在处理时, 处理或匹配内容可能产生冲突的任何边界,同时仍允许使用为表示任意字符而设计的字符转义。

3.2.5.1 在文档格式中指定规范化时的 要求

当规范要求在存储、传输或处理时执行 Unicode 规范化时, 规范作者以及该规范的实现者还需要处理一些其他注意事项:

§

当操作可能从规范化文本 输入产生未规范化输出时,规范必须定义所得输出 是否需要规范化。规范可以规定 某些操作可以选择是否执行规范化;在这种情况下,默认行为应该是执行规范化,并且应该使用明确选项 关闭规范化。

§

要求规范化的规范不得将规范化的实现设为可选。

如果某些实现执行规范化而其他实现不执行,则无法实现互操作性。

必须执行规范化的实现需要考虑以下要求:

§

除非实现首先通过检查确认文本处于规范化形式, 或已自行对文本重新执行规范化,否则不得执行对规范化敏感的操作。 不受这些规则约束的私有系统内部可以建立私有约定,但任何外部可观察结果必须与遵守这些规则时相同。

§

修改文本并执行 对规范化敏感操作的规范化文本处理组件,必须表现得如同每次修改后都执行了规范化, 从而使任何后续对规范化敏感的 操作始终表现得如同正在处理规范化文本。

§

创作工具实现应该警告用户, 或阻止输入或创建以组合标记开头、可能干扰处理、显示或交换的句法内容。

3.2.6 大小写折叠的其他 注意事项

字符串同一性匹配中的一个重要考虑因素,是比较区分大小写还是 不区分大小写。

§

内容作者应该始终使用 一致的大写、小写和混合大小写格式拼写标识符,以便匹配,即使格式或实现支持 大小写折叠匹配。

3.2.6.1 区分大小写的 匹配
§

建议使用区分大小写的匹配来匹配句法内容,包括用户定义的 值。

词汇表通常高度重视内容作者和用户可预测的行为。 区分大小写的匹配最容易实现,也最不容易 引起混淆,因为它通常只是比较底层 Unicode 码位 序列。由于它不受特定语言大小写映射等因素的影响, 因此对于在句法内容中包含上述土耳其语示例等词语的文档作者而言, 产生的意外最少。

不区分大小写通常用于处理可本地化 内容,例如执行自然语言文本 搜索。但是,有时也需要不区分大小写。在这些情况下,形式语言需要考虑 多种实现选择。

3.2.6.2 Unicode 不区分大小写的匹配
§

在包含超出 Unicode 基本拉丁字符(ASCII)范围内容的词汇表中, 定义不区分大小写匹配的规范必须 指定Unicode 完整大小写折叠匹配。

§

规范应该允许用户定义的值使用完整的 Unicode 范围。

词汇表通常应该允许使用广泛的 Unicode 字符,尤其是用户提供的值,从而使最广泛的 语言和文化能够平等使用,而不处于不利地位。因此,大小写折叠等文本操作 需要处理完整的 Unicode 范围,而不仅是选定部分。当需要 不区分大小写的匹配时,这意味着使用Unicode 大小写折叠

Unicode 简单大小写折叠形式不适用于 Web 上的字符串同一性匹配。

3.2.6.3 ASCII 不区分大小写的匹配
§

在仅限于 Unicode 基本拉丁字符(ASCII)子集的词汇表中 定义不区分大小写匹配的规范,可以指定ASCII 不区分大小写的匹配。

词汇表仅限于 ASCII,且不允许 用户定义名称或标识符的形式语言,可以指定ASCII 不区分大小写的匹配。HTML 就是一个示例,它规定对 HTML 规范定义的 元素名和属性名使用 ASCII 不区分大小写的比较。

当且仅当所有标记和标识符都由规范直接定义, 并且这些标识符或标记仅使用 Unicode 的基本拉丁字符 子集时,词汇表才被视为“仅限 ASCII”。如果允许用户定义标识符, 则应该允许使用完整的 Unicode 字符范围 (可根据安全或交换方面的考虑进行适当限制,请参阅 [UTR36]),并使用 Unicode 不区分大小写方式进行同一性匹配。

仅限 ASCII 的词汇表可以存在于允许标识符或值使用 更大 Unicode 范围的文档格式或协议中。例如,[CSS-SYNTAX-3]定义 CSS 样式表的格式时,允许标识符和 值使用完整的 Unicode 范围。但是,CSS 规范始终使用 ASCII 范围的子集定义 CSS 关键字。因此,即使许多样式表包含 非 ASCII 标识符或数据值,CSS 的词汇表仍然仅限于 ASCII。

3.2.6.4 特定语言的 定制

基于区域设置或特定语言的定制,最适合作为自然语言 处理操作的一部分(这超出本文档的范围)。由于特定语言的 大小写映射或大小写折叠定制会产生与通用大小写 折叠规则不同的结果,因此在高度重视可预测性的形式语言中应该避免使用。

§

在词汇表中定义不区分大小写匹配的规范不应指定语言敏感的不区分大小写匹配。

§

如果规定了语言敏感的区分大小写匹配,则 Unicode 大小写 映射应该根据语言进行定制,并且必须指定每项定制所使用的 语言来源。

正在匹配的两个字符串可能使用不同语言,并且还可能出现在第三种语言 上下文中。因此,大小写折叠应使用哪种语言,取决于应用程序和用户 预期。

不建议对形式语言使用特定语言的定制,因为语言 信息可能难以获取、验证或管理,而且所得操作可能 产生令用户沮丧的结果,或根据用户使用的语言配置 或执行匹配的系统配置,对某些用户失败而对其他用户成功。

§

特定语言的操作在适当情况下应该 包括特定语言的大小写折叠。

例如,CSS 操作 text-transform 在用于对字符串执行 大小写映射时是语言敏感的。

虽然 Unicode 大小写折叠是文档格式和协议首选的不区分大小写匹配方式, 但所用语言的映射与默认映射不同的内容作者和用户,仍可能对结果感到意外, 因为他们的预期通常与自己使用的语言一致。

语言敏感的字符串比较通常称为 区域设置敏感,因为大多数编程语言和运行环境 使用各自基于区域设置的 API 访问特定语言的定制。例如, 请参阅 Java 编程语言中的 java.text.Collator 类,或 JavaScript 中的 Intl.Collator

3.2.7 其他匹配定制

§

规范必须明确定义作为匹配过程一部分执行的任何其他 定制。

某些规范可能希望包含其他定制,以帮助在给定 词汇表中执行匹配。例如,移除第 2 节所述的其他文本差异、统一或移除作为 语法一部分的字符,或者执行空白修剪。

任何其他定制都需要避免干扰不同语言在 Unicode 中的表示方式。例如,尝试通过分解文本后移除所有组合字符, 来去除字母重音符号的过程,会破坏依赖组合标记的语言。 示例 2中的天城文文本就是一个示例。(此类过程也无法 移除所有潜在重音符号,并且可能会损害文本的含义和表示形式。)

4. 其他匹配与 处理注意事项

虽然匹配形式语言中的字符串和标记是本文档主要关注的问题,但有时 规范还需要考虑纯字符串相等之外的其他匹配类型。

4.1 正则表达式

§

定义正则表达式语法的规范必须根据 [UTS18] 至少提供基本 Unicode 第 1 级支持,并且应该 提供扩展或定制(第 2 级和第 3 级)支持。

正则表达式语法有时可用于定义格式或协议,因为它们允许用户 指定仅部分已知或以可预测方式变化的值。如本文档 各节所示,字符在 Unicode 中可以采用不同方式 编码,这可能会干扰表达式中字符串的指定或匹配方式。 例如,字符计数可能需要取决于字素边界,而不是 所使用的 Unicode 码位数量;无大小写匹配可能需要考虑大小写 折叠的变化;或者可能需要考虑表达式或正在处理文本的 Unicode 规范化。

Unicode 正则表达式第 1 级支持包括在 正则表达式中指定 Unicode 码位的能力,包括通过使用转义,以及访问 Unicode 字符属性和 大多数正则表达式语法共有的某些边界类型。

第 2 级在此基础上扩展了许多重要功能,尤其是能够根据某些类型的字素簇边界选择文本,以及支持大小写转换 (以上大量讨论的两个主题)。第 3 级支持根据区域设置 [LTLI] 定制 正则表达式,这在形式语言中的用处较小,但在处理可本地化内容时可能有用。

A. 自上一个发布版本以来的变更

本文档的变更(从 2018-04-20 的工作草案开始)可通过 GitHub 提交日志查看。

此版本更改了Unicode 规范大小写折叠规范化步骤Unicode 兼容大小写折叠规范化步骤中可选的规范化步骤。此 版本要求将规范化作为第一步,并将输出规范化设为可选。此变更 基于测试以及与 Unicode 的讨论。

B. 致谢

W3C 国际化工作组和兴趣组 以及其他人士提供了许多意见和建议。工作组谨此感谢: 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, 以及本文档二十(!!)年开发历程中的所有 CharMod 贡献者。

本文档的上一版本由以下人员编辑:

CSS 快照 2026

C. 参考文献

C.1 规范性参考文献

[ASCII]
ISO/IEC 646:1991,信息技术——信息交换用 ISO 7 位编码字符集。URL:https://www.ecma-international.org/publications-and-standards/standards/ecma-6/
[BCP47]
用于标识语言的标签。 A. Phillips,编辑;M. Davis,编辑。IETF。2009 年 9 月。当前最佳实践。URL:https://www.rfc-editor.org/info/rfc5646/
[CHARMOD]
万维网字符模型 1.0: 基础。Martin Dürst;François Yergeau;Richard Ishida;Misha Wolf;Tex Texin 等。W3C。2005 年 2 月 15 日。W3C 推荐标准。URL:https://www.w3.org/TR/charmod/
[CHARREQ]
字符串同一性匹配和字符串 索引要求。Martin Dürst。W3C。2009 年 9 月 15 日。W3C 工作组说明。URL:https://www.w3.org/TR/charreq/
[css]
CSS 快照 2026。Tab Atkins Jr.;Elika Etemad;Florian Rivoal;Chris Lilley;Sebastian Zartner。W3C。2026 年 6 月 22 日。W3C 工作组说明。 URL:https://www.w3.org/TR/css-2026/
[Encoding]
编码标准。Anne van Kesteren。 WHATWG。现行标准。URL:https://encoding.spec.whatwg.org/
[HTML]
HTML 标准。Anne van Kesteren; Domenic Denicola;Dominic Farolino;Ian Hickson;Philip Jägenstedt;Simon Pieters。WHATWG。现行 标准。URL:https://html.spec.whatwg.org/multipage/
[html-bidi]
HTML 和 CSS 中双向文本的附加要求。Aharon Lanin;Richard Ishida。W3C。2015 年 7 月 21 日。W3C 工作组说明。 URL:https://www.w3.org/TR/html-bidi/
[INFRA]
Infra 标准。Anne van Kesteren;Domenic Denicola。WHATWG。现行标准。URL:https://infra.spec.whatwg.org/
[INTERNATIONAL-SPECS]
规范开发者的国际化最佳 实践。Richard Ishida;Addison Phillips。W3C。2025 年 8 月 8 日。W3C 工作组说明。URL:https://www.w3.org/TR/international-specs/
[ISO10646]
信息技术——通用多八位编码字符集(UCS)——第 1 部分: 体系结构与基本多文种平面。。1993。ISO/IEC10646-1:1993。
[LTLI]
万维网的语言标签和区域设置标识符。Addison Phillips。W3C。2020 年 10 月 7 日。W3C 工作草案。URL:https://www.w3.org/TR/ltli/
[RFC2119]
用于 RFC 中指示 要求级别的关键词。S. Bradner。IETF。1997 年 3 月。当前最佳实践。URL:https://www.rfc-editor.org/info/rfc2119/
[RFC3986]
统一资源标识符(URI):通用 语法。T. Berners-Lee;R. Fielding;L. Masinter。IETF。2005 年 1 月。互联网 标准。URL:https://www.rfc-editor.org/info/rfc3986/
[RFC8174]
RFC 2119 关键词中大写与小写的歧义。B. Leiba。IETF。2017 年 5 月。当前最佳实践。URL:https://www.rfc-editor.org/info/rfc8174/
[UAX11]
东亚宽度。Ken Lunde 小林剣。Unicode 联盟。2025 年 7 月 24 日。Unicode 标准附录 #11。URL:https://www.unicode.org/reports/tr11/tr11-44.html
[UAX15]
Unicode 规范化 形式。Ken Whistler。Unicode 联盟。2025 年 7 月 30 日。Unicode 标准附录 #15。URL:https://www.unicode.org/reports/tr15/tr15-57.html
[UAX29]
Unicode 文本 分段。Josh Hadley。Unicode 联盟。2025 年 8 月 17 日。Unicode 标准 附录 #29。URL:https://www.unicode.org/reports/tr29/tr29-47.html
[UAX31]
Unicode 标识符和 语法。Mark Davis;Robin Leroy。Unicode 联盟。2025 年 8 月 20 日。Unicode 标准附录 #31。URL:https://www.unicode.org/reports/tr31/tr31-43.html
[UAX35]
Unicode 区域设置数据标记 语言(LDML)。Mark Davis 等。Unicode 联盟。2020 年 10 月 23 日。Unicode 技术标准 #35。URL:https://www.unicode.org/reports/tr35/tr35-61/tr35.html
[UAX50]
Unicode 垂直文本 布局。Ken Lunde 小林剣;Koji Ishii 石井宏治。Unicode 联盟。2025 年 7 月 24 日。Unicode 标准附录 #50。URL:https://www.unicode.org/reports/tr50/tr50-33.html
[UAX9]
Unicode 双向 算法。Manish Goregaokar मनीष गोरेगांवकर;Robin Leroy。Unicode 联盟。2025 年 8 月 13 日。Unicode 标准附录 #9。URL:https://www.unicode.org/reports/tr9/tr9-51.html
[Unicode]
Unicode 标准。Unicode 联盟。URL:https://www.unicode.org/versions/latest/
[UTR36]
Unicode 安全 注意事项。Mark Davis;Michel Suignard。Unicode 联盟。2014 年 9 月 19 日。Unicode 技术报告 #36。URL:https://www.unicode.org/reports/tr36/tr36-15.html
[UTS18]
Unicode 正则 表达式。Mark Davis。Unicode 联盟。2025 年 1 月 16 日。Unicode 技术 标准 #18。URL:https://www.unicode.org/reports/tr18/tr18-25.html
[UTS39]
Unicode 安全 机制。Mark Davis;Michel Suignard。Unicode 联盟。2025 年 9 月 4 日。 Unicode 技术标准 #39。URL:https://www.unicode.org/reports/tr39/tr39-32.html
[UTS51]
Unicode 表情符号。Mark Davis;Ned Holbrook。Unicode 联盟。2025 年 9 月 4 日。Unicode 技术标准 #51。URL:https://www.unicode.org/reports/tr51/tr51-29.html
[XInclude]
XML 包含(XInclude)1.0 版(第二 版)。Jonathan Marsh;David Orchard;Daniel Veillard。W3C。2006 年 11 月 15 日。 W3C 推荐标准。URL:https://www.w3.org/TR/xinclude/

C.2 资料性参考文献

[CSS-SYNTAX-3]
CSS 语法模块第 3 级。Tab Atkins Jr.;Simon Sapin。W3C。2021 年 12 月 24 日。候选推荐标准草案。URL:https://www.w3.org/TR/css-syntax-3/
[STRING-META]
Web 上的字符串:语言和方向 元数据。Richard Ishida;Addison Phillips。W3C。2024 年 10 月 17 日。W3C 工作组 说明。URL:https://www.w3.org/TR/string-meta/
字符串搜索。Addison Phillips。 W3C。2025 年 1 月 7 日。说明草案。URL:https://www.w3.org/TR/string-search/
[XML10]
可扩展标记语言(XML)1.0(第五 版)。Tim Bray;Jean Paoli;Michael Sperberg-McQueen;Eve Maler;François Yergeau 等。W3C。2008 年 11 月 26 日。W3C 推荐标准。URL:https://www.w3.org/TR/xml/