如何使用字母数字字符串中的数字进行排序?
问题描述:
如果我有一个字符串具有以下格式的数组:如何使用字母数字字符串中的数字进行排序?
[1900] ABC 15
我如何用perl sort
,这样它按第一个数字,然后由第二数组排序?
从perldoc sort这个例子似乎是相关的:
my @new = sort {
($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
||
fc($a) cmp fc($b)
} @old;
答
从文档拉到这个例子给出了这个概念:通过一个标准进行比较,如果他们被发现由cmp
或<=>
equality operators,然后返回0
等于,请进入下一个标准。
所以在这种情况下比较由字符串中的第一个数字,然后由第二个。
use warnings;
use strict;
use feature 'say';
my @old = ('[1900] ABC 15', '[1900] ABC 5', '[1800] ABC 20');
my @new = sort {
my ($a1, $a2) = $a =~ /([0-9]+)/g;
my ($b1, $b2) = $b =~ /([0-9]+)/g;
$a1 <=> $b1 or $a2 <=> $b2;
} @old;
say for @new;
打印
[1800] ABC 20 [1900] ABC 5 [1900] ABC 15
如果排序需要在从大到小的顺序互换a
和比较b
。
这可以通过预先计算整个列表的正则表达式来更有效地完成,以便在每次比较元素时不会重新执行它们。文档示例的延续显示了这一点,最后一个版本是Schwartzian transform。
但请记住,这种优化只适用于较大的数据集,而对于简单的计算它们的开销也很重要。 以上基本sort
一般就足够了。
注意 一个[0-9]
由\d
匹配而且还有其它字符(360更有人告诉我),它是支持Unicode。 /a
字符集修改器的情况并非如此,自5.14起可用。但是,这具有的效果比限制\d
更广泛。在perlre中搜索/a
。 因此,我在这里使用了0-9
来进行精度和小的效率测量,并且不限制\s
,\w
和POSIX字符类。
答
我写了一个函数做了这种排序前一段时间。 它使用字符串中的所有数字进行数字排序。 我不在乎表现,对不起。希望能帮助到你。
sub num_sort($$) {
my ($a,$b)[email protected]_;
my @sa=reverse grep /./s, split /(\d+)/,$a;
my @sb=reverse grep /./s, split /(\d+)/,$b;
for (;;) {
last if [email protected] || [email protected];
my $ea=pop @sa;
my $eb=pop @sb;
my $rc= ($ea <=> $eb) || ($ea cmp $eb);
if ($rc) {
return $rc;
}
}
return @sa <=> @sb;
}
当你说Perl时,你应该在上下文中显示一些代码。这个'[1900] ABC 15'没有任何意义。 – sln
我想你会需要定义你自己的排序子程序,然后检查你想要比较的字符串部分。你可能会追加第二个数字到第一个来获得一个数字(190015)进行比较。 –
我没有让你失望。 – sln