Perl:通过数组过滤来创建一个新数组

时间:2013-11-03 14:22:31

标签: arrays perl

我正在尝试在程序中过滤分隔文本文件的数组。此文本文件中的数组如下所示:

YCL049C                   1     511.2465  0 0 MFSK
YCL049C                   2    4422.3098  0 0 YLVTASSLFVALT
YCL049C                   3    1131.5600  0 0 DFYQVSFVK
YCL049C                   4    1911.0213  0 0 SIAPAIVNSSVIFHDVSR
YCL049C                   5     774.4059  0 0 GVAMGNVK
..
.

我对该程序的这一部分的代码是:

my @msfile_filtered;
my $msline;
foreach $msline (@msfile) {

    my ($name, $pnum, $m2c, $charge, $missed, $sequence) = split (" ", $msline);
    if (defined $amino) {

        if ($amino =~ /$sequence/i) {

            push (@msfile_filtered, $msline);

        }

    }
    else {

        push (@msfile_filtered, $msline);

    }

}

$ amino将只是一个将由用户输入的字母,并且对应于最后一个字段$ sequence。用户实际输入$ amino并不是必需的,所以我需要复制这个数组并保持不变,如果是这种情况(因此else语句)。 @msfile_filtered数组是空的,但我不确定为什么,任何想法?

编辑:只是为了澄清,每个字段之间只有一个空格,我从notpad ++复制并粘贴它,因此添加了额外的间隔。文件本身在字段之间只有一个空格。

提前致谢!

2 个答案:

答案 0 :(得分:3)

尝试查找匹配行的正则表达式是向后的。要在大海捞针中找到针,您需要写$haystack =~ /needle/,而不是相反。

另外,为简化逻辑,如果$aminoundef,请完全跳过循环。我会按如下方式重写您的代码:

if (defined $amino)
{
    foreach $msline (@msfile)
    {
        my ($name, $pnum, $m2c, $charge, $missed, $sequence) = split(" ", $msline);
        push @msfile_filtered, $msline if ($sequence =~ /$amino/i);
    }
} else
{
    @msfile_filtered = @msfile;
}

您可以将此进一步简化为单个grep语句,但这开始变得难以阅读。这样一行的一个例子可能是:

@msfile_filtered =
    defined $amino
        ? grep { ( split(" ", $_ ) )[5] =~ /$amino/i } @msfile
        : @msfile;

答案 1 :(得分:1)

拆分应该使用多个空格,而正则表达式反之亦然。

首先调试以在分割后检查值是否正确。

此外,您必须交换正则表达式变量,如下所示:

 if ($sequence =~ /$amino/i) {

现在你要检查$ amino是否包含$ sequence,这显然不是