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.数据库在创 ...
随机推荐
- elasticsearch template
# curl -XPUT localhost:9200/_template/template_1 -d '{"template" : "te*","s ...
- hello1以及hello2的部分代码分析
(一)1.GreetingServlet.java源码文件: @WebServlet("/greeting") //以@WebServlet注释开头,注释指定相对于上下文根的URL ...
- centos6安装rabbitmq
一.安装依赖包 yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ k ...
- 【计算机网络】TCP的流量控制和拥塞控制
TCP的流量控制 1. 利用滑动窗口实现流量控制 如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失.所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收. 利用滑动 ...
- 关于php条形码生成(barcode),修改样式
今天听错了需求,以为要重新设计条形码,第一次制作这个,经过搜索使用的barcode这个第三方的,具体使用步骤网上很多就不在这里详细介绍了.主要是今天遇到的样式修改问题: barcode经过查看是无法自 ...
- 366. Find Leaves of Binary Tree输出层数相同的叶子节点
[抄题]: Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all ...
- Bootstrap+PHP fileinput 实现多图上传 这是ajax上传,只能单张单张图片地上传
插件及源代码可以在这里下载 http://www.jq22.com/jquery-info5231下面是根据下载的demo进行补充:使用bootstrap界面美观,可预览,可拖拽上传,可配合ajax异 ...
- stc15w wave
1. 定时器和延时 #include "15W4KxxS4.h" #define FOSC 12000000 #define CLK (65536-FOSC/2/12/1000) ...
- 统计百分比的一个SQL脚本
统计一个表中一个百分比的SQL脚本,不过这个是个万分比,这个数据类型要调一调 ),) declare @num3 decimal,@num4 decimal declare @percent deci ...
- SpringBoot集成redis,使用@Cachexxxx
一.引入相关依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...