Unicode 字符串排序规则(二):如何比较字符串
一、UCA 简介
Unicode Collation Algorithm (UCA) 是 Unicode 规定的如何比较两个字符串大小的算法,也是事实上的标准。我们先来看下它的几个特征。
1.1 Multi-Level Comparison
为了处理字符串比较的复杂性,UCA 采用了多级比较的方法。
当比较两个字符串时,先比较最重要的特征——字母。如果字母相同,再比较重音 (accent)。如果重音还相同,再比较大小写。依次类推,这些特征之间的顺序可以改变。

如上图所示,首先比较基本字符串,然后依次是 Accent、 Case、Punctuation等,最后比较是否完全相等。
一定要注意,Unicode 码点的顺序不是排序的依据。
The position of characters in the Unicode code charts does not specify their sort order.
为何要采样多级比较
考虑一个例子,我们有a < ä && e < ë && a < e && ä < ë,如果我们仅仅采用单级比较的话,显然有a < ä < e < ë。
比较字符串ae和äa。我们想要得到的结果肯定是äa < ae。如果按照单级比较的话,由于a < ä,我们会得到ae < äa。
使用多级比较,可以优先处理主要矛盾。
1.2 Canonical Equivalence
在 Unicode 中,可能出现两个不同码点序列表示的是同一个字符串,即这两个序列具有 Unicode等价性。这些具有 Unicode 等价性的字符串在排序时,应该被认为是同样的。下表是一些 Unicode 等价性的例子。

1.3 Contextual Sensitivity
在某些语言中,字符串的比较不仅仅是单个字符序列的比较,和字符出现的上下文有关。UCA 必须处理好这些事情,如下所示:

1.4 Customization
在实际使用中,UCA 应该可以处理一些用户自定义的规则,包括但不限于:
- Language。
排序结果应该符号目标语言使用者的预期。 - Case Ordering
有时大写在前,有时小写在前。 - Script Order
用户可能希望一种文字出现在另一种文字之前。
b < ב < β < б [Latin < Hebrew < Greek < Cyrillic] versus
β < b < б < ב [Greek < Latin < Cyrillic < Hebrew] - Numbers
用户可能希望把字符串按照数字排序,如A2 < A10。
二、UCA 排序算法处理过程
2.1 Normalize
使用 Unicode 规范化算法,把字符串以标准等价方式来分解 (Normalization Form Canonical Decomposition, NFD)。
2.2 Produce Array
对字符串中的每一个字符进行多级量化,转化为数组,便于之后的比较。

如上所示,每一个字符对应一个 collation element;每一个元素中用.分隔不同等级的权重的值。比如c的第一权重是0706,第二权重是0020,第三权重是0002。
2.3 Form Sort Key
把数组中所有非零权重的值按照等级连接起来,组成一个 sort key。


如果指定了只比较等级 1、2,那么等级 3 就不会在 sort key 中出现。
2.4 Compare
使用一种方法对字符串的 sort key 进行排序。下面是一个排序结果的例子。

最后的排序结果是"cab" <<< "Cab" << "cáb" < "dab$"。
- 对于字符串 1 和 2,第一个区别是 0002 VS 0008 (Level 3).
- 对于字符串 2 和 3,第一个区别是 0020 VS 0021 (Level 2).
- 对于字符串 3 和 4,第一个区别是 0706 VS 0712 (Level 1).
三、其他
- 生成Collation Element 时,具体的值可以被修改
CLDR 指定了如何根据语言和地区进行处理,还包括其他内容。 字符串有时需要预处理
在某些具体的情形下,需要进行预处理,下面是一些例子。- McBeth -> MacBeth
- St. -> Saint 或者 St. -> Street
- 去掉冠词
- 加入额外信息。对于汉字来说,有多音字。
UCA 只是规定了一个算法。具体的实现可以不同,只要保证和 UCA 结果相同。
四、参考
Unicode 字符串排序规则(二):如何比较字符串的更多相关文章
- Unicode 字符串排序规则(一):如何确定单个字符的顺序
一.一个具体的例子引发的问题 当今是国际化的时代,多种语言可能同时显示在屏幕上.比如一个人可能喜欢听华语歌.英文歌.韩文歌和日语歌,又比如他的联系人中有中国人.英国人.日本人.韩国人以及有英文名字的中 ...
- php中的字符串常用函数(二) substr() 截取字符串
//substr($str, startIndex, length) //截取方向都是从左向右的. //length不写默认截取到最后一个. //length为正是个数(包括开头的个数),为负是索引( ...
- OpenJudge计算概论-字符串排序
/*====================================================================== 字符串排序 总时间限制: 1000ms 内存限制: 6 ...
- Openjudge-计算概论(A)-字符串排序
描述 参考整数排序方法,设计一种为字符串排序的算法,将字符串从小到大输出 输入 第一行为测试数据组数t, 后面跟着t组数据.每组数据第一行是n,表示这组数据有n行字符串,接下来是要排序的n行字符串.每 ...
- 字符串之————图文讲解字符串排序(LSD、MSD)
本篇文章围绕字符串排序的核心思想,通过图示例子和代码分析的方式讲解了两个经典的字符串排序方法,内容很详细,完整代码放在文章的最后. 一.键索引计数法 在一般排序中,都要用里面的元素不断比较,而字符串这 ...
- 数据库排序规则的冲突(理解collate Chinese_PRC_CI_AS)
之前碰到了数据库排序规则冲突问题,即百度或者 Google 的老话题: “ 无法解决 equal to 操作中‘ sql_latin1_general_cp1_ci_as ’和‘ chinese_pr ...
- MS SQL 排序规则总结
排序规则术语 什么是排序规则呢? 排序规则是根据特定语言和区域设置标准指定对字符串数据进行排序和比较的规则.SQL Server 支持在单个数据库中存储具有不同排序规则的对象.MSDN解 ...
- sql server 排序规则
/* 排序规则根据特定语言和区域设置的标准指定对 字符串 数据 进行排序和比较的规则. 以 ORDER BY 子句为例:如果按升序排列,说英语的人认为字符串 Chiapas 应排在 Col ...
- sqlserver之排序规则和ETL不支持sqlserverdatetime2的问题
sqlserver的排序规则大概分为Windows 排序规则和 SQL Server 排序规则.数据在安装的时候,默认不设置会默认为SQL_Latin1_General_CP1_CI_AI.数据库在创 ...
随机推荐
- xadmin 常见错误
版本: Django==2.0.5 xadmin==0.6.1 djangorestframework==3.9.0 1.No module named 'django.core.urlresolve ...
- 退出vim编辑器(转)
在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了. 偶有小白,刚接触linux,要修改某个文本文件,不可能像WINDOWS那样操作,更有甚者,进入VI编辑器后,无法退出以致 ...
- hbase--知识点总结2
--用java操作hbase 1.配置jar包环境 创建hbase项目 --> 新建folder文件夹 --> 将hbase相关jar包全部导入到java项目之中 --> add b ...
- 转)Ubuntu16.04下安装DDD(Data Display Debugger)
以下转自:http://www.linuxdiyf.com/linux/26393.html 前两天在Linux论坛偶然间看到了DDD这个软件,根据介绍是一个gdb界面化的调试软件,这正是我找了好 ...
- Head First Servlets & JSP 学习笔记 第七章 —— 作为JSP
<%@ …… %> 这是指令 <%@ page ……import="java.util.Date" %> 这是page指令,import是page指令的一个 ...
- message [Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property
springmvc前台字符串,后台Date类型字段.时间强转失败 数值:18年12月31日 15:43:21 解决方法,给时间字段加注释 @DateTimeFormat(pattern = " ...
- PHP开发——进制转换
常用进制 l 10进制:有10个基本数,分别为0.1.2.3.4.5.6.7.8.9,运算规则”逢10进1”: l 8进制:有8个基本数,分别为0.1.2.3.4.5.6.7,运算规则”逢8进1” ...
- (转)Android四大组件——Activity跳转动画、淡出淡入、滑出滑入、自定义退出进入
文章转自:http://blog.csdn.net/qq_30379689/article/details/52494270 Activity跳转动画.淡入淡出.滑入滑出.自定义退出进入 前言: 系统 ...
- zabbix3.x自动发现主机
在服务器比较多的情况下,配置加入群组,添加模板是非常费时费力的,所以利用自动发现主机.自动添加群组和模板是非常好的办法. 两步走 1.配置发现规则 2.配置发现动作 1.前提在服务器是上部署了agen ...
- jquery 判断 元素是否具有某个class
两种方法如下: 1.hasClass(‘classname’) 2.is(‘.classname’) 例子: 1.使用is(‘.classname’)的方法 $('div').is('.redColo ...