en_US.UTF-8 区域设置中出现意外的排序顺序

en_US.UTF-8 区域设置中出现意外的排序顺序

在试图回答的同时这个关于SQL排序的问题,我注意到一个sort我没想到的命令:

$ export LC_ALL=en_US.UTF-8  
$ echo "T-700A Grouped" > sort.txt
$ echo "T-700 AGrouped" >> sort.txt
$ echo "T-700A Halved" >> sort.txt
$ echo "T-700 Whole" >> sort.txt
$ cat sort.txt | sort
T-700 AGrouped
T-700A Grouped
T-700A Halved
T-700 Whole
$ 

为什么700 A排序在上面700A,而700A在上面呢700 W?我希望前面有一个空格A,与后面的字符无关。

如果您使用 C 语言环境,它可以正常工作:

$ export LC_ALL=C
$ echo "T-700A Grouped" > sort.txt
$ echo "T-700 AGrouped" >> sort.txt
$ echo "T-700A Halved" >> sort.txt
$ echo "T-700 Whole" >> sort.txt
$ cat sort.txt | sort
T-700 AGrouped
T-700 Whole
T-700A Grouped
T-700A Halved
$ 

答案1

排序是分多次完成的。每个角色都分配有三个(或有时更多)权重。假设这个例子的权重是

         wt#1 wt#2 wt#3
space = [0000.0020.0002]
A     = [1BC2.0020.0008]

为了创建排序键,字符串字符的非零权重被连接起来,一次一个权重级别。也就是说,如果权重为零,则不会添加相应的权重(如 的开头所示" A")。所以

       wt#1   -- wt#2 ---   -- wt#3 ---
" A" = 1BC2   0020   0020   0002   0008
       A      sp     A      sp     A

       wt#1   wt#2   wt#3
"A"  = 1BC2   0020   0008
       A      A      A

       wt#1   -- wt#2 ---   -- wt#3 ---
"A " = 1BC2   0020   0020   0008   0002
       A      A      sp     A      sp

如果你对这些数组进行排序,你会得到你看到的顺序:

       1BC2   0020   0008               => "A"
       1BC2   0020   0020   0002   0008 => " A"
       1BC2   0020   0020   0008   0002 => "A "

这是实际发生情况的简化;看到Unicode 排序算法更多细节。上面的示例权重实际上来自标准表,省略了一些细节。

相关内容