Sort
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 $
排序是在多遍中完成的。每個角色都分配了三個(或有時更多)權重。假設對於這個例子,權重是
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 排序算法。上面的範例權重實際上來自標準表,省略了一些細節。