对字符串执行 Unicode 规范化(假设没有孤立的组合字符)的结果是否与将字符串拆分为字素簇、分别规范化每个簇然后连接规范化的字素簇的结果相同?(如果是这样,这是否仅适用于规范化形式的子集?)
问这个主要是出于对 Unicode 如何工作的兴趣,并找出可能存在哪些潜在的边缘情况,而不是作为具体应用程序的一部分。
对字符串执行 Unicode 规范化(假设没有孤立的组合字符)的结果是否与将字符串拆分为字素簇、分别规范化每个簇然后连接规范化的字素簇的结果相同?(如果是这样,这是否仅适用于规范化形式的子集?)
问这个主要是出于对 Unicode 如何工作的兴趣,并找出可能存在哪些潜在的边缘情况,而不是作为具体应用程序的一部分。
不,这通常是不正确的。Unicode 标准警告不要假设连接规范化字符串会产生另一个规范化字符串。从UAX #15开始:
在使用规范化函数时,重要的是要认识到 在字符串连接下没有一个规范化形式是封闭的。也就是说,即使两个字符串 X 和 Y 被规范化,它们的字符串连接 X+Y 也不能保证被规范化。
Unicode 文本分割算法的许多方面都是可定制的;该标准主要只提供在大多数情况下有用的默认值,但可以在出于特定目的需要时被覆盖。因此,不能保证两个符合 Unicode 的应用程序甚至会就字素边界的位置达成一致。一个具体的例子是遗留字素簇和扩展字素簇之间的区别。
在前者中,具有Grapheme_Cluster_Break
属性值Spacing_Mark
或的字符Prepend
不充当字素扩展器,而在后者中它们可以。从 Unicode 12.1 开始,有十二个这样的字符具有非零规范组合类。如果您使用传统的字素簇定义,这些字符会破坏您的方法,例如按以下顺序:
<U+1D158, U+1D16D, U+1D166>
这是
因为组合增强点和组合 sprechgesang 词干都是Spacing_Mark
,所以这个序列实际上被分成三个遗留字素簇,每个只有一个字符的长度,因此会自动归一化。然而,由于它们的 CCC 值,整个字符串的真正规范化会切换点和词干的位置。
如果我们忽略调整算法的可能性,只关注标准中严格定义的扩展字素簇,那么据我所知,单独标准化每个字素簇应该会产生与一次标准化整个字符串相同的结果,但是不能正式保证该标准的未来修订版不会改变这一点。