除非找到另一个模式,否则删除带有模式的行?

时间:2015-11-20 07:47:11

标签: regex perl

我有一个非常混乱的数据文件,看起来像这样

========
Line 1
dfa====dsfdas==
Line 2 
df  as TOTAL ============

我想删除所有仅包含“=”的行,但如果TOTAL也在行中,请保留该行。

我的代码如下:

for my $file (glob '*.csv') {
    open my $in, '<', $file;        
    my @lines;
    while (<$in>) {
        next if /===/; #THIS IS THE PROBLEM
        push @lines, $_;
    }   
    close $in;
    open my $out, '>', $file;
    print $out $_ for @lines;
    close $out;
}

我想知道是否有一种方法可以使用正则表达式在perl中执行此操作。我想的是让“TOTAL”成为条件1而“===”成为条件2.然后,如果两个条件都满足,则脚本单独留下线,但如果只满足一个或零,那么该线被删除?

提前致谢!

4 个答案:

答案 0 :(得分:2)

您需要\A^来检查字符串是否以=开头。请在正则表达式中填充anchor,如下所示:

next if /^===/;

或者只有=将存在:

next if /^=+/;

它将跳过以=开头的所有行。+用于匹配前一个令牌的一次或多次匹配。

修改

然后你应该使用Negative look behind之类的

next if /(?<!TOTAL)===/

这将确保您===前面没有TOTAL。

由于TOTAL===之间可能出现任何字符,我建议您使用两个正则表达式来确保字符串包含===但不包含TOTAL喜欢:

next if (($_ =~ /===/) && ($_ !~ /TOTAL/))

答案 1 :(得分:1)

你可以在断言背后使用负面看法

next if /(?<!TOTAL)===/

匹配===时不在TOTAL前面

答案 2 :(得分:1)

作为一般规则,您应该避免使正则表达式更复杂。将太多东西压缩成单个正则表达式可能看起来很聪明,但它使得理解和调试变得更加困难。

那么为什么不做复合条件?

E.g。像这样:

TOTAL

只要不包含var myURL = document.location; document.location = myURL + "?a=parameter"; ,就会跳过包含location.hash = 'a=parameter' 的所有行。并且不需要高级正则表达式功能,我保证你会让你的维护程序员诅咒你。

答案 3 :(得分:0)

您当前的正则表达式会在字符串中的任何位置拾取包含字符串===的任何内容。

Hello===      Match
===goodbye    Match
=======       Match
foo======bar  Match
===           Match
=             No Match
Hello==       No Match
=========     Match

如果您想确保它只选取由=个符号组成的字符串,那么您需要锚定到该行的开头和结尾,并考虑任意数量的=个符号。将起作用的正则表达式如下:

next if /^=+$/;

每个符号含义:

^ The start of the string
= A literal "=" sign
+ One or more of the previous 
$ The end of the string

这将从字符串的开头到仅由=个符号组成的字符串的末尾拾取任意长度的字符串。

Hello===      No Match
===goodbye    No Match
=======       No Match
foo======bar  No Match
===           Match
=             Match
Hello==       No Match
=========     Match

我建议你阅读perl的正则表达式,如果你知道正在发生什么,每个符号意味着它可以是一个非常强大的工具。 http://perldoc.perl.org/perlre.html#Regular-Expressions

编辑: 如果你想跳过匹配TOTAL和=的一行,那么只需要进行2次检查:

next if(/TOTAL/ and /=+/)

这可以通过一行正则表达式完成。但是为什么要把它变得复杂而且不那么可读呢?