我有一个非常混乱的数据文件,看起来像这样
========
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.然后,如果两个条件都满足,则脚本单独留下线,但如果只满足一个或零,那么该线被删除?
提前致谢!
答案 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 /=+/)
这可以通过一行正则表达式完成。但是为什么要把它变得复杂而且不那么可读呢?