摘要:微软使用的措辞……至少可以说令人困惑。似乎应该完成简单的大写映射,但我不能确定。
背景
部分混淆可能是案例折叠和案例映射之间的差异。大小写映射将每个字符映射到指定的大小写。大小写折叠虽然基于小写,但被定义为产生无大小写字符(UTR #21 §1.3)。
现在有 case mapping 和 case fold 两种变体,simple和full。与简单的转换不同,完整的转换可以更改字符串长度,正如您正确指出的那样,这里不需要。该规范特别提到了简单,并且可能是这个答案中唯一明确的事情。我确实觉得有必要提及当前的 Unicode 标准 (6.3.0) 提到默认大小写转换是完整的,以供将来参考,尽管 Microsoft 参考的版本 (3.1.1) 似乎没有做出这种区分。
规格分析
(...)使用 Unicode 默认大小写转换算法、简单大小写转换变体(简单大小写折叠)转换为大写,并附上以下注释。<2> 比较每个大写的UTF-16 代码点二进制值。
对我来说,这句话似乎暗示他们想要大写,并且只是通过说大小写折叠而不是大小写映射而犯了一个错误。但是随后您引用的参考文献出现了:
对于 Windows XP 和 Windows Server 2003:复合文件实现符合 Unicode 3.0.1 默认大小写转换算法,简单大小写折叠 ( http://www.unicode.org/Public/3.1-Update1/CaseFolding-4.txt )除了以下例外。
他们实际上提到了案例折叠数据文件!在这一点上,我不知道该怎么想。我的主要思路是微软希望折叠外壳,尽管错误地认为它是基于上壳而不是下壳。虽然这甚至有点牵强,但它是我能够调和这种可能的矛盾的最接近的方法,我希望有更好的解释。
我在第 2.6.1 节中发现以下支持某种形式的大写:
[...] 使用特殊的不区分大小写的大写映射来比较目录条目名称,如Red-Black Tree中所述。
请注意,他们实际上在这里使用了术语映射。
例外清单
查看上述 Windows XP 和 Windows Server 2003 的例外列表,大多数条目都是减法,这表明 Microsoft 想要保持不同的代码点。但是,在表中,代码点实际上是按与 Unicode 大小写折叠数据文件相反的顺序列出的。
对此的一种解释是,它只是一个显示怪癖。这个想法被他们减去案例转换的最后一行击落了0x03C2 -> 0x03C2
。该转换在数据文件中不存在,因为转换0x03C2 -> 0x03C3
存在(未列出的案例转换被视为转换为自身)。
另一种解释是他们实际上错误地认为它的反向映射是正确的。正如您所提到的,这会遇到麻烦,因为反向映射并不总是那么简单。否则,这个解释就好了。
第三种解释是认为他们对 Unicode 大小写折叠数据文件的引用是错误的。这当然让我感到不安,但如果他们最初确实意味着案例映射,他们可能只是提供了链接作为快速参考点。他们提到的例外列表确实有列标题,例如“小写 UTF-16 代码点”,但我们知道大小写折叠实际上是无大小写的。
顺便说一句,我确实查看了后来的操作系统的例外列表,希望获得更多的见解。我发现更多的困惑。特别是加法让0x03C3 -> 0x03A3
我很烦恼。由于异常列表和 Unicode 文件以相反的顺序列出了它们的代码点,看来转换已经在数据文件中,不需要添加。这部分规范不想被理解!
结论
如果您已经阅读了以上所有内容,您可能会猜到这个结论会不太理想。很明显,在一个或多个点上,规范是错误的,但很难说在哪里。实际上,根据您对需要进行哪种案例转换的解释,存在三种可能性。
- 简单的大写映射
- 简单大小写折叠,后跟简单大写映射
- 简单的案例折叠
对我来说,微软似乎确实想要大写字母。从那里我相信案例折叠参考是一个错误,因此我的猜测是他们只想要简单的大写映射。
我非常怀疑这是最后一个简单的案例折叠唯一选项。其他两个选项都会给出非常相似的结果,只有少量代码点可能会给出不同的结果。
似乎唯一可以确定的方法是联系 Microsoft,或者煞费苦心地查看二进制文件以查看遵循哪种方法。