如何仅返回与数组的任何值不匹配的行?

时间:2011-03-06 12:58:41

标签: regex perl

我正在尝试将CS​​V文件中的每一行与使用Perl存储在数组中的每个元素(字符串)进行比较。我想返回/打印到CSV文件中的行,只有当它与数组中的任何字符串不匹配时。我已经尝试了很多类型的循环来实现这一目标,但不仅没有找到解决方案,而且我的尝试都没有真正给我提供关于我哪里出错的线索。以下是我试过的一些循环样本:

while (<CSVFILE>) {
   foreach $i (@lines) {
        print OUTPUTFILE $_ if $_ !~ m/$i/;
     }; #foreach
}; #while

foreach $i (@lines) {
open (CSVFILE , "< $csv") or die "Can't open $csv for read: $!";
  while (<CSVFILE>) {
    if ($_ !~ m/$i/) {
      print OUTPUTFILE $_;
    }; #if
  }; #while
close (CSVFILE) or die "Cannot close $csv: $!";
}; #foreach

以下是我正在尝试的CSV文件示例:

1,c.03_05delAAG,null,71...
2,c.12T>G,null,24T->G,5...
3,c.87C>T,null,96C->T,82....

数组元素(带正则表达式转义字符):

c\.12T\>G
c\.97A\>C

假设只有上面的输入数据,我希望能回来:

1,c.03_05delAAG,null,71...
3,c.87C>T,null,16C->T....

因为它们不包含数组中的任何元素。这是Hashes发挥作用的情况吗?除了标准的“字典”定义之外,我还没有很好的处理它们。如果有人能帮助我解决这个问题,我将不胜感激。这一点我可能只是手动执行,因为没有那么多我尽快需要这个,但是因为我无法在其他任何地方找到任何答案我认为它值得一提。

1 个答案:

答案 0 :(得分:2)

使用Perl 5.10.1或更高版本,以便您可以应用smart matching。 另外,当你处理两个循环时,不要使用隐式$_,它会让人感到困惑并且容易出错。

以下代码(未经测试)可能会起到作用:

use 5.010;
use strict;
use warnings;
use autodie;

...

my @regexes = map { qr{$_} } @lines;

open my $out, '>', $outputfile;
open my $csv, '<', $csvfile;

while (my $line = <$csv>) {
    print $out $line unless $line ~~ @regexes;
}

close $csv;
close $out;

顺便说一下,你的代码不起作用的原因是,如果@lines中的任何元素不匹配,它会打印一行,并且是这样的。