Perl和Unix如何排序,以相同的顺序排序Unicode字符串?

Dio*_*lis 24 unix sorting unicode perl locale

我试图让Perl和GNU/Linux sort(1)程序就如何对Unicode字符串进行排序达成一致.我跑的排序LANG=en_US.UTF-8.在Perl程序中,我尝试了以下方法:

他们中的每一个都失败了以下错误(来自Perl方面):

  • 输入未排序:[----,]在[($ 1)之后出现
  • 输入未排序:[...]在[&]之后出现
  • 输入未排序:[($ 1)在[1]之后出现

只为我工作的方法参与设置LC_ALL=C排序,并在Perl使用8位字符.但是,这样就没有正确排序Unicode字符串.

ike*_*ami 5

使用Unicode :: Sort或Unicode :: Sort :: Locale是没有意义的.您不是要尝试基于Unicode定义进行排序,而是尝试根据您的语言环境进行排序.这use locale;是为了什么.

我不知道为什么你没有得到想要的顺序排列出来cmpuse locale;.

您可以处理解压缩的文件.

for q in file1.uniqc file2.uniqc ; do
   perl -ne's/^\s*(\d+) //; for $c (1..$1) { print }' "$q"
done | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)

当然,它需要更多的临时存储空间,但您可以获得所需的顺序.


我发现一个案例use locale;没有导致Perl's sort/ cmp给出与sort实用程序相同的结果.奇怪的.

$ export LC_COLLATE=en_US.UTF-8

$ perl -Mlocale -e'print for sort { $a cmp $b } <>' data
(
($1
1

$ perl -MPOSIX=strcoll -e'print for sort { strcoll($a, $b) } <>' data
(
($1
1

$ sort data
(
1
($1
Run Code Online (Sandbox Code Playgroud)

说实话,sort实用工具很奇怪.


在评论中,@ ninjalj指出,奇怪的可能是由于权重未定义的字符.在比较这些字符时,排序是不确定的,因此不同的引擎可能会产生不同的结果.重新创建确切顺序的最佳选择是sort通过IPC :: Run3使用该实用程序,但听起来并不能保证始终产生相同的顺序.

  • Perl不使用UCA进行排序,而glibc使用ISO 14651吗? (2认同)

小智 1

我无法直接回答,但我在获取一个简单的脚本来正确排序塞尔维亚拉丁文本时遇到问题,我发现https://www.perl.com/pub/2012/06/perlunicook-demo-of-unicode-collat ​​ion -and-printing.html/,复制了他的设置(我的实际处理比他的简单得多),并最终获得了该语言和区域设置的正确字母排序。在https://www.perl.com/pub/2012/04/perlunicook-standard-preamble.html/的整套指南中,有任何人需要了解的有关 Unicode 语言排序的信息。

\n

我假设你想对希腊语进行排序。这是我从指南中复制和改编的非常简单的版本,排序正确。

\n
# min required setup for trial sort\nuse utf8;\nuse v5.14; # for locale sorting and unicode_strings\nuse Unicode::Normalize;\nuse Unicode::Collate::Locale;\nmy @words = qw{\n        \xce\x97\n        \xce\x99\xce\xb8\xce\xac\xce\xba\xce\xb7\n        \xcf\x83\'\n        \xce\xad\xce\xb4\xcf\x89\xcf\x83\xce\xb5\n        \xcf\x84\xce\xbf\n        \xcf\x89\xcf\x81\xce\xb1\xce\xaf\xce\xbf\n        \xcf\x84\xce\xb1\xce\xbe\xce\xaf\xce\xb4\xce\xb9.\n        \xce\xa7\xcf\x89\xcf\x81\xce\xaf\xcf\x82\n        \xce\xb1\xcf\x85\xcf\x84\xce\xae\xce\xbd\n        \xce\xb4\xce\xb5\xce\xbd\n        \xce\xb8\xce\xac\xce\xb2\xce\xb3\xce\xb1\xce\xb9\xce\xbd\xce\xb5\xcf\x82\n        \xcf\x83\xcf\x84\xce\xbf\xce\xbd\n        \xce\xb4\xcf\x81\xcf\x8c\xce\xbc\xce\xbf.\n};\nprint "Unsorted: @words\\n";\nmy $coll = Unicode::Collate::Locale->new( locale => "el_GR" );\nmy @sorted_words = $coll->sort(@words);\nprint "Sorted: @sorted_words\\n";\n
Run Code Online (Sandbox Code Playgroud)\n