2013-11-03 87 views
0

我试图在我的程序中过滤分隔文本文件的数组。从这个文本文件中的排列是这样的: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); 

    } 

} 

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

编辑:只是为了澄清,每个领域之间只有一个空间,我复制并粘贴这从notpad ++,所以额外的间距被添加。文件本身只在字段之间有一个空格。

在此先感谢!

回答

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; 
+0

是很可能的,OP做不提供用户输入示例 –

+0

我使用原始问题中的示例,位于顶部。 (以YCL049C开头的五行) –

+0

感谢您的帮助!当没有输入$氨基的输入时,循环跳过查找和数组保持不变,但是当我输入$氨基的值时,@ msfile_filtered不包含只有指定字母的序列。实际上它什么都没有。我将发挥作用并回报 – user2941526

1

拆分应该采取多个空格,而正则表达式变量反之亦然。

首先进行调试以检查拆分后的值是否正确。

此外,您必须交换这样您正则表达式的变量:

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

现在你检查是否$个包含$序列,这显然是不

+0

拆分正常工作,从记事本++复制和粘贴有点误导。该文件本身只有一个空间 – user2941526

+0

之间确定,抱歉,但似乎是这样。那么正则表达式呢? – foibs

+0

@folbs:正则表达式的确是根本原因。 –