这主要是一个我非常好奇的理论问题.(我不是试图通过自己编写或任何东西来做到这一点,我不是在重新发明轮子.)
我的问题是大写/小写等价表如何适用于Unicode.
例如,如果我必须在ASCII中执行此操作,我会使用一个字符,如果它在[az]范围内,我会将A和a之间的差值相加.
如果它不属于该范围,我会为10个左右的重音字符加上一个小等价表加上ñ.(或者,我可以只有一个包含256个条目的完整等价数组,其中大多数与输入相同)
但是,我猜测有一种更好的方法来指定Unicode中的等价,假设有数十万个字符,理论上,可以添加一种新语言或一组字符(我期待你当发生这种情况时,不需要修补窗口).
Windows是否为每个字符都有一个巨大的硬编码等价表?或者这是如何实现的?
一个相关的问题是SQL Server如何实现基于Unicode的重音不敏感和不区分大小写的查询.它是否有一个内部表格,告诉它éëeÉÉ和Ë都等同于"e"?
在比较字符串时,这听起来不是很快.
它如何快速访问索引?它是否已将索引值转换为其"基本"字符,对应于该字段的整理?
有谁知道这些东西的内部?
谢谢!
我将解决这个问题的MS SQL Server部分,但"正确"的答案实际上取决于支持的语言和应用程序.
在SQL Server中创建表时,每个文本字段都具有隐式或显式指定的排序规则.这会影响排序顺序和比较行为.对于大多数英语(美国)语言环境,默认值为Latin1_General_CI_AS或Latin 1,不区分大小写,Accent-Sensitive.这意味着,例如,a = A,但是!=Ä和a!=ä.您还可以使用重音不敏感(Latin1_General_CI_AI)将"A"的所有变音符号变量视为相等.
一些语言环境支持其他类别的比较; 例如,法语下载含有变音符号的单词与德语有所不同.土耳其语认为无点我和点缀我在语义上不同,所以如果你使用土耳其语,不区分大小写,重音敏感的校对,我和我甚至不匹配不区分大小写的比较.
您可以更改每个数据库,每个表,每个字段的排序规则,以及一些成本,甚至每个查询.我的理解是索引根据指定的归类顺序进行规范化,这意味着索引基本上保留了原始字符串的扁平化版本.例如,对于不区分大小写的排序规则,Apple和apple将存储为apple.在搜索之前,使用相同的排序规则对查询进行展平.
在日语中,还有另一类归一化,其中全宽和半宽字符如ア=ア,在某些情况下,两个半宽字符被扁平化为单个语义等效字符(バ=バ).最后,对于某些语言,还有另一个带有复合字符的蜡球,其中孤立的变音字符可以与其他字符组成(例如,ä中的变音符号是一个字符,由简单形式a组成).越南语,泰语和其他一些语言有此类别的变体.如果存在规范形式,则Unicode规范化允许将组合和分解的形式视为等效形式.通常在进行任何比较之前应用Unicode规范化.
总而言之,对于不区分大小写的比较,您执行的操作与比较ASCII范围字符串时的操作非常相似:将比较的左侧和右侧展平为"小写"(例如),然后将数组比较为二进制阵列.不同之处在于您需要1)将字符串规范化为相同的unicode形式(kC或kD)2)根据该语言环境的规则将字符串规范化为相同的情况3)根据重音敏感规则对重音进行规范化4)根据二进制比较进行比较4)如果适用,例如在排序的情况下,使用额外的二级和三元排序规则进行比较,其中包括类似于某些语言中"M"之前的"Mc"排序的事物.
是的,Windows存储了所有这些规则的表.除非您通过控制面板的东亚语言支持和复杂脚本支持添加对它们的支持,否则在每次安装中都不会默认获取所有这些内容.
有一个映射文件,其中包含具有1:1映射比率的所有大小写映射.通常,操作系统/框架/库支持特定版本的Unicode,并且由于这种情况下映射文件是版本化的,因此您可以获得特定操作系统/框架/库/支持的任何版本的Unicode的映射.
有关Unicode案例映射的更多信息,请参阅:http://www.unicode.org/faq/casemap_charprop.html