为什么JavaScript的Intl.Collator比较和传统UTF-16比较特殊字符结果不同?
差异原因
两种比较逻辑的底层规则完全不同:
- 传统UTF-16比较直接对比字符的Unicode码点数值:正斜杠
/的码点为十进制47,下划线_的码点为十进制95,47<95,所以返回-1,排序结果为['/', '_'],该逻辑仅和字符编码相关,和使用场景、语言区域无关。 Intl.Collator是为自然语言排序设计的API,遵循Unicode排序算法(UCA)和对应区域的定制排序规则,完全不依赖码点数值。在en区域的默认排序规则里,下划线的排序优先级高于正斜杠,所以返回1,排序结果为['_', '/']。
这不是ECMAScript实现的Bug
这个表现完全符合ECMA-402规范的要求,Intl.Collator的设计初衷就是要和默认的码点排序做区分,分别适配不同的场景:
- 码点排序适合机器处理的标识符、编码类内容排序
Intl.Collator适合面向普通用户展示的自然语言内容排序,符合不同语言使用者的日常排序习惯
容易被遗漏的知识点
sensitivity: 'base'的配置会忽略字符的大小写、重音差异,只保留最基础的字符权重排序,这种场景下非字母类符号的排序优先级完全由区域规则定义,和码点没有对应关系。- 不同区域的排序规则差异极大,哪怕是相同的字符组合,在
en、fr、jp等不同区域配置下的排序结果都可能出现差异。
en locale下其他存在同类差异的字符组合
这类组合非常多,几乎所有标点符号、特殊字符的排序都可能和码点顺序不一致,举几个常见的例子:
- 连字符
-(码点45)和点号.(码点46):码点排序-在前,en区域Collator排序.在前 - 问号
?(码点63)和左方括号[(码点91):码点排序?在前,en区域Collator排序[在前 - 艾特符
@(码点64)和反斜杠\(码点92):码点排序@在前,en区域Collator排序\在前
内容的提问来源于stack exchange,提问作者akaustav
相关产品推荐
相关产品推荐

