正常化和排序
某些 Unicode 字符具有多种等效的二进制表示形式。这些表示形式由组合和/或复合 Unicode 字符集组成。 因此,两个字符串可能看起来是相同的,但实际上由不同的字符组成。 如果一个字符存在多种表示形式,将会使排序操作趋于复杂。 对于此问题的解决方法是对每个字符串进行正常化,然后使用序号比较对字符串进行排序。
Unicode 标准定义了一个称为正常化的过程,该过程可以在给定某个字符的任何等价二进制表示形式时,返回该字符的单一二进制表示形式。 Unicode 标准定义了四种不同的算法(称为范式),可以用来对字符串进行正常化。 各个范式遵循不同的规则,因此对于输入的字符串会生成不同的二进制表示形式。 但是,如果两个字符串被正常化为同一范式,则随后可以使用序号(不区分大小写)比较对这两个字符串进行比较。
两个字符串的序号比较是对两个表示正常化字符串的 String 对象中相应的每一对 Char 结构的数值或码位的二进制比较。 .NET Framework 提供了多种执行序号比较的方法。
应用程序可以使用以下过程对字符串进行正常化和排序:
从输入源(例如文件或用户输入)中获取要进行排序的两个字符串。
使用 String.Normalize() 方法将两个字符串正常化为范式 C,或者使用 String.Normalize(NormalizationForm) 方法将两个字符串正常化为所选范式。
使用序号字符串比较(例如带有 Ordinal 或 OrdinalIgnoreCase 值的 Compare(String, Int32, String, Int32, Int32, StringComparison) 方法)来比较这两个字符串。 比较操作可以确定是第一个字符串在词法上排在第二个字符串之前,还是这两个字符串在词法上相等。
根据步骤 3 的结果,在已排序的输出中发出字符串。 如果字符串不相等,则按升序或降序顺序发出字符串。
如果字符串相等,则可以首先发出其中任一字符串,除非按某个特征而不是词法顺序来安排字符串更为合适。 例如,如果应用程序正在对文件名进行排序,但同时也在将每个文件的属性写到输出中,则可以按照文件创建日期的顺序写入相等的文件名。
重复此过程,直到完成对所有输入的排序。
有关 .NET Framework 中的范式支持的更多信息,请参见 NormalizationForm 枚举说明。 有关对字符串进行正常化的更多信息,请参见 Normalize 方法。
有关规范化、字符分解和等效的更多信息,请参见 Unicode Home Page(Unicode 主页)上的“Unicode Standard Annex #15”(Unicode 标准附件 15)“Unicode Normalization Forms”(Unicode 范式)。