您不希望根据第二列的内容将第一列中混合大小写的内容混合在一起,但这正是不区分大小写排序为您提供的。它认为共享一个案例折叠的事物是相同的。
这组 Unicode 记录的种类:
abc a
Abc d
Abc b
abc e
abæ g
当然是这样的:
abæ g
abc a
Abc b
Abc d
abc e
这是因为第一个和第二个字母在所有五行中都是“相同的”(即,它们的大小写是相同的),所以第一个不同的字母是第三个,它是 æ course 在 c 之前,这是其他四个记录的第三个字母。
对于剩下的行,它们的前三个字母都相同,所以决定性的是它们的第四个字母,现在给出序列 a、b、d、e。空格(通常)在 Unicode 排序中并不重要,因为它是字母数字排序而不是代码点排序。我们在这里只考虑字母,除非它们一直到大小写都相同,然后才考虑其他代码点。
这就是 Unicode 排序的工作原理。
除非您要求,否则 Unicode 排序算法不会关注丹麦语排序。该代码点的默认 DUCET 条目将 æ 和 å 等内容放在 a 旁边,将 ø 放在 o 旁边。 OED 按以下顺序对这些条目进行排序:
allergist
allergy
Allerød
allers
allethrin
这是因为“Allerød”中的 o 在“allergy”中的 g 之后,在 allers 中的 s 之前。变音符号仅在其他所有内容相同时才重要,因此假设的“alleroc”将在“Allerød”之前,假设的“allerog”将在它之后但在“allers”之前。
这就是 Unicode 中排序的工作原理。斯堪的纳维亚人讨厌它,因为他们认为它应该做他们独特的国家系统所做的任何事情,但 Unicode 并不偏向于特定的语言。如果你想要你的白痴,你必须使用语言环境排序。要像这样获得特定于丹麦语言环境的排序:
abc a
Abc b
Abc d
abc e
abæ g
您需要使用指定的丹麦语言环境来运行排序,而不是使用损坏的 POSIX 方式,而是使用 Unicode 方式。
首先,你必须放弃尝试使用sort(1)。更糟糕的是没有用:它不可靠且具有欺骗性。如果您有 Unicode 数据,则应该使用 Unicode 排序,无论是像 OED 那样未经修改还是为您的小村庄修改。
要产生正常的 Unicode 排序,您必须使用:
#!/usr/bin/env perl
use strict;
use warnings;
use open qw(:std :utf8);
use utf8;
use Unicode::Collate;
my @lines = <<'End_of_Lines' =~ /\S.*\S\n/g;
abc a
Abc d
Abc b
abc e
abæ g
End_of_Lines
my $collator = Unicode::Collate->new();
print $collator->sort(@lines);
虽然要获得受语言环境限制的非默认“只为你”排序,但您需要:
#!/usr/bin/env perl
use strict;
use warnings;
use open qw(:std :utf8);
use utf8;
use Unicode::Collate::Locale;
my @lines = <<'End_of_Lines' =~ /\S.*\S\n/g;
abc a
Abc d
Abc b
abc e
abæ g
End_of_Lines
my $collator = Unicode::Collate::Locale->new(locale => "da");
print $collator->sort(@lines);
Unicode::Collate 模块是自 Perl 版本 v5.6 以来的标准。
Unicode::Collate::Locale 模块是自 Perl 版本 v5.14 以来的标准包含,但在早期版本中可以轻松地从 CPAN 安装:
$ sudo perl -MCPAN -e "install Unicode::Collate::Locale"
您必须为此使用 Perl 的原因是因为您根本无法信任供应商的语言环境根据 Unicode 排序算法工作,无论是否修改了语言环境。我从未见过两个不同的系统以相同的方式工作,这意味着每对中至少有一个坏了,也许两者都坏了。相反,您可以保证无论您身在何处,UCA 都会始终以相同的方式运行。它不关心你的终端可以显示什么。它不关心字体。它不在乎你是否被重定向。它不关心你运行的是哪个 shell。不管你的格特鲁德阿姨是否碰巧在一个月内的第 5 个星期一运行代码。它只是起作用,并且在每种情况下每次都以相同的方式起作用。使用 UCA。不接受替代品。
但仅仅因为您使用 UCA 并不意味着您需要接受默认排序。 UCA 的设计非常适合剪裁。如果你想要一个语言环境排序,这很容易——如果有该语言环境的 CLDR 数据,那肯定是微不足道的。如果你想做一种书名和电影标题,或者姓氏比名字更重要的人名,并且所有苏格兰 Mc- 和 Mac- 的名字都排在 M- 之前,但彼此无关,所有这些都是使用 UCA 非常容易。您可以想象的任何事情都可以完成,而且通常非常轻松。关键是,使用 UCA,您总是从保证以完全相同的方式工作的行为开始,而不管平台或偏见如何。这意味着当您想对其应用自己的自定义时,您可以依赖它的工作方式。没有这种保证,一切都将丢失。
您可以获得符合 UCA here 的 Unix sort(1) 程序的预制命令行替换(嗯,有点)。它当然不做领域,但它确实做得更多。