使用正则表达式进行Perl排序

时间:2014-06-04 19:18:12

标签: regex perl sorting

我有一个像这样的perl数组字符串:

my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)", ... );

如何用括号中的整数对数组进行排序?

4 个答案:

答案 0 :(得分:5)

使用transform比较字符串

中的第一个数字
use strict;
use warnings;

my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)");

my @sorted = map {$_->[0]}
             sort {$a->[1] <=> $b->[1]}
             map {[$_, /\b(\d+)\b/]} @arr;

print "$_\n" for @sorted;

输出:

gene2 (50)
gene1 (100)
gene3 (120)

答案 1 :(得分:3)

Perl中的sort built-in允许您传递代码引用作为其第一个参数,以定义应如何进行排序。在此代码ref中,您可以使用任何您想要的功能。

由于您希望使用正则表达式,因此创建与括号中的数字匹配的sub并在排序函数中使用它是有意义的。

您需要为$a$b调用一次,这两个变量将针对每轮排序对进行相互比较。您应该使用<=> operator,它用于按升序排序数字。

这是一个非常详细的版本。

use strict;
use warnings;
use Data::Dump;

my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)",  );

dd sort { get_number($a) <=> get_number($b) } @arr;

sub get_number {
  my ( $string ) = @_;
  return $1 if $string =~ m/\((\d+)\)/;   
  return 0; # assume it goes last if there is no number
}

输出:

("gene2 (50)", "gene1 (100)", "gene3 (120)")

答案 2 :(得分:2)

这显示了直截了当的方式。 sort块将$aa$bb分别设置为$a$b中的数字值。然后使用<=>以数字方式对它们进行比较。

除非基本技术证明太慢,否则不需要更加模糊的转换方法。

use strict;
use warnings;
use 5.010;

my @arr = ( "gene1 (100)", "gene2 (50)", "gene3 (120)",  );

my @sorted = sort {
  my ($aa) = $a =~ / \(  (\d+)  \) /x;
  my ($bb) = $b =~ / \(  (\d+)  \) /x;
  $aa <=> $bb;
} @arr;

say for @sorted;

<强>输出

gene2 (50)
gene1 (100)
gene3 (120)

答案 3 :(得分:1)

List::UtilsBy CPAN模块提供了一个函数nsort_by,它通过按数字顺序排序来排序值列表,每个值上的代码块返回的值。

在您的情况下,它可用于提取该数字:

use List::UtilsBy 'nsort_by';

@sorted = nsort_by { m/\((\d+)/ and $1 } @strings

这比使用代码的常规sort调用更有效,可以直接从$a$b提取和比较两个数字,因为它只需从每个数字中提取数字价值一次,而不是每次成对比较一次。