一、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 应该可以处理一些用户自定义的规则,包括但不限于:

  1. Language。
    排序结果应该符号目标语言使用者的预期。
  2. Case Ordering
    有时大写在前,有时小写在前。
  3. Script Order
    用户可能希望一种文字出现在另一种文字之前。
    b < ב < β < б [Latin < Hebrew < Greek < Cyrillic] versus
    β < b < б < ב [Greek < Latin < Cyrillic < Hebrew]
  4. 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. 对于字符串 1 和 2,第一个区别是 0002 VS 0008 (Level 3).
  2. 对于字符串 2 和 3,第一个区别是 0020 VS 0021 (Level 2).
  3. 对于字符串 3 和 4,第一个区别是 0706 VS 0712 (Level 1).

三、其他

  1. 生成Collation Element 时,具体的值可以被修改
    CLDR 指定了如何根据语言和地区进行处理,还包括其他内容。
  2. 字符串有时需要预处理
    在某些具体的情形下,需要进行预处理,下面是一些例子。

    1. McBeth -> MacBeth
    2. St. -> Saint 或者 St. -> Street
    3. 去掉冠词
    4. 加入额外信息。对于汉字来说,有多音字。
  3. UCA 只是规定了一个算法。具体的实现可以不同,只要保证和 UCA 结果相同。

四、参考

  1. UNICODE COLLATION ALGORITHM
  2. UNICODE NORMALIZATION FORMS
  3. CLDR

Unicode 字符串排序规则(二):如何比较字符串的更多相关文章

  1. Unicode 字符串排序规则(一):如何确定单个字符的顺序

    一.一个具体的例子引发的问题 当今是国际化的时代,多种语言可能同时显示在屏幕上.比如一个人可能喜欢听华语歌.英文歌.韩文歌和日语歌,又比如他的联系人中有中国人.英国人.日本人.韩国人以及有英文名字的中 ...

  2. php中的字符串常用函数(二) substr() 截取字符串

    //substr($str, startIndex, length) //截取方向都是从左向右的. //length不写默认截取到最后一个. //length为正是个数(包括开头的个数),为负是索引( ...

  3. OpenJudge计算概论-字符串排序

    /*====================================================================== 字符串排序 总时间限制: 1000ms 内存限制: 6 ...

  4. Openjudge-计算概论(A)-字符串排序

    描述 参考整数排序方法,设计一种为字符串排序的算法,将字符串从小到大输出 输入 第一行为测试数据组数t, 后面跟着t组数据.每组数据第一行是n,表示这组数据有n行字符串,接下来是要排序的n行字符串.每 ...

  5. 字符串之————图文讲解字符串排序(LSD、MSD)

    本篇文章围绕字符串排序的核心思想,通过图示例子和代码分析的方式讲解了两个经典的字符串排序方法,内容很详细,完整代码放在文章的最后. 一.键索引计数法 在一般排序中,都要用里面的元素不断比较,而字符串这 ...

  6. 数据库排序规则的冲突(理解collate Chinese_PRC_CI_AS)

    之前碰到了数据库排序规则冲突问题,即百度或者 Google 的老话题: “ 无法解决 equal to 操作中‘ sql_latin1_general_cp1_ci_as ’和‘ chinese_pr ...

  7. MS SQL 排序规则总结

    排序规则术语        什么是排序规则呢? 排序规则是根据特定语言和区域设置标准指定对字符串数据进行排序和比较的规则.SQL Server 支持在单个数据库中存储具有不同排序规则的对象.MSDN解 ...

  8. sql server 排序规则

    /*   排序规则根据特定语言和区域设置的标准指定对  字符串  数据 进行排序和比较的规则.   以 ORDER BY 子句为例:如果按升序排列,说英语的人认为字符串 Chiapas 应排在 Col ...

  9. sqlserver之排序规则和ETL不支持sqlserverdatetime2的问题

    sqlserver的排序规则大概分为Windows 排序规则和 SQL Server 排序规则.数据在安装的时候,默认不设置会默认为SQL_Latin1_General_CP1_CI_AI.数据库在创 ...

随机推荐

  1. request设置cookies

    mycookie = { "PHPSESSID":"56v9clgo1kdfo3q5q8ck0aaaaa" } request.get(url,cookies ...

  2. P1147连续自然数和-(尺取法)

    https://www.luogu.org/problemnew/show/P1147 题意:输入一个n,求连续几个数加起来等于n,输出这几个连续的数的第一个和最后一个.10<=n<=20 ...

  3. 引用计数——深拷贝&浅拷贝

    下面是用代码实现: private: char *data; size_t use_count; public: //构造函数 String_rep() { if(str == NULL) { dat ...

  4. aptana怎么显示空格 tab和回车等

  5. as3中的embed

    actionscript3允许把外部swf直接用Embed标记嵌入到主类中(当然用UrlLoader动态加载也行) 原 作者:菩提树下的杨过出处:http://yjmyzz.cnblogs.com 关 ...

  6. np.cumsum()函数和正则表达式的含义

  7. centos部署redis主从

    安装环境 CentOS 6.5 .CentOS 7.4 主Redis:10.159.44.175 从Redis: 10.159.44.176.10.159.44.177 Redis下载和安装 在3台机 ...

  8. 9. Palindrome Number (JAVA)

    Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same back ...

  9. swift 警告框 - 自定义按钮颜色,图片

    1.封装 弹框http://www.hangge.com/blog/cache/detail_651.html import UIKit extension UIAlertController { / ...

  10. Docker架构

    Docker使用客户端-服务器(C/S)架构模式,使用远程API来管理和创建Docker容器. Docker容器通过Docker镜像来创建. 容器与镜像的关系类似于面向对象编程中的对象和类. Dock ...