這是一個真正的雙模雙待,有回答我的兩個最終目標:什麼是Perl的「標準字符串比較順序」?
- 什麼是標準的字符串比較順序,在力學方面?
- 這有什麼更好的名稱,所以我可以更新文檔?
Perl的文檔sort說,沒有塊,sort
使用「標準字符串比較順序」。那是什麼命令?應該有一個更好的名字。對於這個問題,我特別指的是locale沒有生效的情況,因爲它定義了它自己的順序。
在過去的幾年中,我們通常稱爲「ASCIIbetically」的標準排序順序。它在Learning Perl和許多其他書籍。但是,這個詞是過時的。自從5.6版本開始,Perl就已經可以識別Unicode。談論ASCII是老派。由於Perl也支持Unicode,所以它知道字符串。在sv.c,Perl_sv_cmp
知道約locale
,bytes
和UTF-8。前兩個很容易。但我對第三名沒有信心。
/*
=for apidoc sv_cmp
Compares the strings in two SVs. Returns -1, 0, or 1 indicating whether the
string in C<sv1> is less than, equal to, or greater than the string in
C<sv2>. Is UTF-8 and 'use bytes' aware, handles get magic, and will
coerce its args to strings if necessary. See also C<sv_cmp_locale>.
=cut
*/
當Perl使用UTF-8排序時,它究竟是什麼排序呢?字符串編碼的字節,它表示的字符(包括標記也許?)或其他?我認爲這是sv.c相關行(線6698爲提交7844ec1):
pv1 = tpv = (char*)bytes_to_utf8((const U8*)pv1, &cur1);
如果我讀的是正確的(使用我的生鏽C),pv1
被強制八位字節,變成UTF-8,然後強制轉換成字符(在C意義上)。我認爲這意味着它按照UTF-8編碼進行排序(即UTF-8用來表示代碼點的實際字節)。另一種說法是,它不排序字形。我想我已經說服了我自己正在閱讀這個權利,但是你們中的一些人比我更瞭解這方面的內容。
從這個,下一個有趣的路線是6708:
const I32 retval = memcmp((const void*)pv1, (const void*)pv2, cur1 < cur2 ? cur1 : cur2);
對我來說,看起來像一旦pv1
和pv2
,其被裹挾到char *
,現在只是比較逐字節,因爲他們被強制爲void *
。那麼memcmp
會發生什麼?看起來它只是根據我讀過的各種文檔比較位數?再次,我想知道我在從bytes-> utf8-> char-> bytes的行程中丟失了什麼,就像Unicode標準化步驟一樣。檢出Perl_bytes_to_utf8
在utf8.c沒有幫我回答這個問題。
作爲一個便箋,我想知道這是否與Unicode Collation Algorithm一樣?如果是這樣,爲什麼Unicode::Collate存在?從它的外觀來看,我不認爲Perl的sort
處理規範等價。
有一個簡單的方法來看看他們是否按字節排序UTF-8序列:如果你這樣做,你會得到A 2009-11-04 23:40:20
(回覆自己)是的,當所有語言環境都設置爲「C」時,我就是這麼看的。似乎證實了你對源代碼的分析。 – 2009-11-04 23:46:37
那麼,你想觀察的序列取決於你認爲序列已經應該是什麼,這就是爲什麼有一個Unicode排序算法。 :) – 2009-11-04 23:56:51