如何在Unicode中将字符串设置为大写/小写?

时间:2008-11-18 02:37:24

标签: unicode string theory low-level uppercase

这主要是一个我非常好奇的理论问题。 (我不是试图通过自己编码或其他任何东西来做到这一点,我不是在重新发明轮子。)

我的问题是大写/小写等价表如何适用于Unicode。

例如,如果我必须在ASCII中执行此操作,我会使用一个字符,如果它在[a-z]范围内,我会将A和a之间的差值相加。

如果它不属于该范围,我会为10个左右的重音字符加上一个小等价表加上ñ。 (或者,我可以只有一个包含256个条目的完整等价数组,其中大部分与输入相同)

然而,我猜测有一种更好的方法来指定Unicode中的等价,因为有数十万个字符,理论上,可以添加一种新语言或一组字符(而且我是期待在发生这种情况时你不需要修补窗口。)

Windows是否为每个字符都有一个巨大的硬编码等价表?或者这是如何实现的?

一个相关的问题是SQL Server如何实现基于Unicode的重音不敏感和不区分大小写的查询。它是否有一个内部表格告诉它éëeÉÉ和Ë都等同于“e”?

在比较字符串方面听起来不是很快。

如何快速访问索引?它是否已将索引值转换为其“基本”字符,对应于该字段的整理?

有没有人知道这些东西的内部结构?

谢谢!

4 个答案:

答案 0 :(得分:16)

我将解决此问题的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 :(得分:12)

有一个映射文件,其中包含具有1:1映射比率的所有大小写映射。通常,操作系统/框架/库支持特定版本的Unicode,并且由于这种情况下映射文件是版本化的,因此您可以获得特定操作系统/框架/库/无论支持的任何版本的Unicode的映射。

有关Unicode案例映射的详细信息,请参阅:http://www.unicode.org/faq/casemap_charprop.html

答案 2 :(得分:3)

大多数书写系统没有单独的大写和小写字母。根据维基百科,例外情况包括“罗马,希腊,西里尔和亚美尼亚字母”。

所以没有那么多信件需要担心。 This page表明大范围的字符遵循一个简单的方案,即将1加到大写字符中以获得小写的等价物(当然也有一些例外)。

答案 3 :(得分:1)

正确的答案有点复杂,取决于你想要做什么。

在比较字符串时,为了排序或搜索应用程序,在UTS #10: "Unicode Collation Algorithm".中指定了正确使用的算法。不区分大小写是混合的一部分,但是有不同的方法来表示很多字符,而且应用程序经常使用需要将各种表示视为等同。

排序规则依赖于语言环境。当您将结果排序以显示给用户时,这主要是一个问题。忽略规则可能会使用户感到沮丧甚至导致安全漏洞。

如果你只是试图将文字大写以用于展示目的,那么那里的规则也可能很棘手;有一对多的转换和其他问题。根据区域设置,相同的字母可能会以不同方式进行大写。字母在一个单词中的位置可以有所作为。还有一个独特的“标题案例”概念,你只想把每个单词的第一个字母大写。有时字符的标题大小写与大写字母不同。