似乎sort
在诸如>>b
$ cat test
a
>>b
b
c
>
>>
$ sort test
>
>>
a
b
>>b
c
Run Code Online (Sandbox Code Playgroud)
我希望该>>b
行是第三行输出,sort
但它是第五行。为什么这样做,有没有办法sort
让我的预期输出?
我正在使用 GNU/Linux Ubuntu 16.04。
现代语言环境中的排序算法非常复杂。
每个字符(实际上是整理元素,它可以由几个字符的序列组成,例如 Czech ch
)被赋予许多整理权重,这些权重决定了它们的排序顺序。
比较两个字符串时,首先使用所有字符的第一个权重,如果两个字符串与第一个权重排序相同,则稍后使用其他权重来决定平局。
例如,在许多语言环境中e
,é
和E
具有相同的主要权重(它们属于相同的等价类,它们都匹配[=e=]
)。
因此,当比较例如echo
, été
and 时Enter
,在第一遍中,e
,é
和E
具有相同的主要权重,第二个字符将确定顺序(c
before n
before t
)。
比较été
, Été
, 时Ete
,在第一遍之后,它们的排序都相同,因此我们使用第二遍使用二级权重。在典型的 GNU 语言环境中,拉丁文字字符的第二个权重用于区分重音的优先级(首先没有重音,然后是尖音、重音、短音、抑扬音……)。然后我们需要使用第三个权重来决定été
和Été
,这将基于大小写(在大多数语言环境中首先是小写)。甚至有些字符最终排序相同,因为它们的所有权重都相同。
这用于以与字典类似的方式对文本进行排序,就像人类所做的那样。
在字典中,您会发现空格和大多数标点符号也被忽略。例如de facto
在debut
和之间排序devoid
。空格字符的第一个权重是 IGNORE。
在 GNU 系统上,您会发现/usr/share/i18n/locales/iso14651_t1_common
(路径可能随发行版而异)中定义的核心整理规则。在那里,你会看到:
ifdef UPPERCASE_FIRST
<CAP>
else
<MIN>
endif
[...]
ifdef UPPERCASE_FIRST
[...]
<MIN> # 10
[...]
else
[...]
<CAP> # 9
[...]
endif
[...]
order_start <SPECIAL>;forward;backward;forward;forward,position
<U0020> IGNORE;IGNORE;IGNORE;<U0020> # 32 <SP>
[...]
<U003E> IGNORE;IGNORE;IGNORE;<h> # 140 >
[...]
ifdef DIACRIT_FORWARD
order_start <LATIN>;forward;forward;forward;forward,position
else
order_start <LATIN>;forward;backward;forward;forward,position
endif
[...]
<U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e
<U00E9> <e>;<ACA>;<MIN>;IGNORE # 260 é
[...]
<U0045> <e>;<BAS>;<CAP>;IGNORE # 577 E
<U00C9> <e>;<ACA>;<CAP>;IGNORE # 578 É
Run Code Online (Sandbox Code Playgroud)
这说明了我们刚才所说的。space 和>
的前 3 个权重都设置为IGNORE
。它仅适用于对前 3 个权重进行排序的字符串,它们的相对顺序将被考虑(>
在空格之前,因为它<h>
会在未指定的整理符号之前列出<U0020>
)。
在定义UPPERCASE_FIRST
(如/usr/share/i18n/locales/tr_TR
)的语言环境中,大写字母将首先出现(在第三遍中)。与DIACRIT_FORWARD
某些语言环境一样de_DE
可以决定颠倒第二遍的变音符号顺序。
>
和 >>
排序在1相同的ST,2次和3次通过。在4日,>
排序前>>
为空字符串排序之前的一切。
>>b
排序之后,b
因为它们在前 3 遍中排序相同,但在第四遍中,b
是 IGNORE,所以>
更大。它比c
第一遍(>
忽略和b
之前c
)要少......你明白了。
现在,如果您查看C
语言环境定义。这要简单得多。只有一个权重,权重基于从 U+0000 到 U+10FFFF 的代码点值。所以SPC
(U+0020) 在>
(U+003E) 之前排序,在b
(U+0062) 之前排序,在c
(U+0063)之前排序。没有一个字符会被忽略。
请注意,至少对于 GNU libc,当涉及到比较函数(strcoll()
和 co.,如 所用sort
)时,将忽略在 C 语言环境定义文件中定义的顺序。不管 的值LC_CTYPE
,与LC_COLLATE=C
,strcoll()
都等价于strcmp()
。由于比较总是在字节值上,即使这些字节对应于其 unicode 代码点排序相反的字符(如 ISO-8859-15 字符集中的 0xA4 U+20AC EURO SIGN 与 A5 U+00A5 YEN SIGN) , so LC_ALL=C sort
and LC_COLLATE=C sort
(如果LC_ALL
没有另外设置)将在那里产生相同的效果。
归档时间: |
|
查看次数: |
132 次 |
最近记录: |