2017-08-28 263 views
-1

如果我有一个字符串具有以下格式的数组:如何使用字母数字字符串中的数字进行排序?

[1900] ABC 15 

我如何用perl sort,这样它按第一个数字,然后由第二数组排序?

perldoc sort这个例子似乎是相关的:

my @new = sort { 
    ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0] 
         || 
       fc($a) cmp fc($b) 
} @old; 
+0

当你说Perl时,你应该在上下文中显示一些代码。这个'[1900] ABC 15'没有任何意义。 – sln

+0

我想你会需要定义你自己的排序子程序,然后检查你想要比较的字符串部分。你可能会追加第二个数字到第一个来获得一个数字(190015)进行比较。 –

+0

我没有让你失望。 – sln

回答

4

从文档拉到这个例子给出了这个概念:通过一个标准进行比较,如果他们被发现由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字符类。

+0

使用'/ a'修饰符,'\ d'只匹配'[0-9]',请参阅:http://perldoc.perl.org/perlretut.html – Toto

+0

@Toto谢谢,这就是我所指的通过“_without modifiers_”。从那时起,我不想详细介绍'/ aa',这是一个附注。但最好说出来,谢谢。 – zdim

+0

@Toto我没有把它添加到文本中,感谢评论。 – zdim

0

我写了一个函数做了这种排序前一段时间。 它使用字符串中的所有数字进行数字排序。 我不在乎表现,对不起。希望能帮助到你。

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; 
} 
相关问题