一、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. user story

    What is a user story? A user story is a short description of something that your customer will do wh ...

  2. js 菜单收起和展开

  3. MySql/Oracle树形结构查询

    Oracle树形结构递归查询 在Oracle中,对于树形查询可以使用start with ... connect by select * from treeTable start with id='1 ...

  4. oralce 中union 和union all 的简单使用说明

    union:对两个结果集进行合并操作:不包括重复行:同时进行默认规则的排序: union all:对两个结果集进行合并操作:包括重复行:不排序:

  5. SpringCloud详解

    来源于纯洁的微笑 http://www.ityouknow.com/spring-cloud.html

  6. CDH hue下定时执行hive脚步

        今天在看oozie时发现能在hue中执行hive 脚本,主要是hue 和 oozie结合使用,下面介绍下怎么使用的,挺恶心的,哈哈(在这里就不哔哔了) 提交oozie定时作业 1.进入hue界 ...

  7. Python设计模式 - UML - 总览

    说到设计模式就不得不涉及建模思想,说到建模思想自然而然会应用UML,目前业界开源的UML工具很多,用起来也非常便捷.近几年来随着软件应用领域开发模式转向快速迭代试错,UML在敏捷开发,尤其是web及m ...

  8. [Java核心技术笔记]并发

    Runnable Runnable接口是函数式接口 //Runnable接口 public interface Runnable { void run(); } //用lambda表达式创建实例 Ru ...

  9. FortiGate日常检查

    1.1)CPU利用率:由于防火墙有芯片,正常的流量都走芯片转发,不走cpu,只有开了utm相关的应用层防护功能和DDOS之类的,才会走cpu,所以一般cpu都不会占用太多,甚至很多时间都是0%, 如果 ...

  10. 384. Shuffle an Array数组洗牌

    [抄题]: Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. i ...