这是一个真正的双模双待,有回答我的两个最终目标:什么是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