我正在编辑一堆SQL文件,我需要删除查询中的日期引用。但是,文件的写入方式是逻辑运算符,如OR和AND本身在线上,其余的相关参数在另一行上。像这样:
OR
field.lastupdate > DATE_SUB(CURDATE(), INTERVAL 31 DAY))
AND
*some more code*
我想删除OR(并且它也可以是AND)直到换行符,在本例中,在第二个括号之后。但是我想保留其余的代码。
我认为正则表达式应该是直截了当的,除了我如何在OR之后忽略换行符但是停在下面的换行符?
我应该注意,我要移除的某些日期行以";"
结尾,我不想删除。
这是一个更完整的例子,我希望能够解决问题:
OR
x.is_deleted = 0
OR
x.lastupd > DATE_SUB(CURDATE(), INTERVAL 31 DAY))
AND
(j.active = 1
OR
j.is_deleted = 0
OR
j.lastupd > DATE_SUB(CURDATE(), INTERVAL 31 DAY));
所以你看我想要保留第一个“OR”并且它是以下行,
删除第二个“OR”及其后面的行。
保持“AND”及其后面的行以及下面的“OR”及其对应的行。
然后删除最后的“OR”和它的行,同时离开最后的“;”。
答案 0 :(得分:3)
$sql =~ s/\b(?:OR|AND)[ \t]*[\n\r]+(?=.*DATE).*(?<![;\s])//mg;
删除OR
(或AND
)以及以下行中的内容(如果其中包含DATE
),但可能的结尾;
除外。
注意这样的简单正则表达式不适用于您更新的示例,因为删除的行上有右括号,属于其他行。
的示例答案 1 :(得分:0)
嗯,我不是在句子之后只有一个句子有OR / AND。
这个想法是跟踪一个标志,告诉你在前一句中你遇到了一个OR / AND。
也许你可以做这样的事情。
open(FPTR, "infilename")
or die "\nCan't open $filename for reading: $!\n";
open(OUT, ">outfilename")
or die "\nCan't open $OUT for writing: $!\n";
my $st=0;
while(<FPTR>)
{
if($_ =~ m/OR$/ || $_ =~ m/AND$/) {
$st=1;
}
elsif($st==1 $$ **match to your sentence**) {
$st=0;
next;#since you want to remove the line followed by line containing OR/AND
}
else {
print OUT $_;
#i'm not sure if here also you need to set $st=0;
}
}
close(FPTR);
close(OUT);
答案 2 :(得分:0)
有时候,更简单的解决方案是最好的。此脚本将仅(重新)打印与您要删除的行的描述不匹配的行。如果找到一个,则会打印一个尾随的分号;
。它会将行保留为已读。
它依赖于没有行为空,并且没有想要的行包含单词DATE_SUB。
<强>用法:强>
$ script.pl input.txt > output.txt
<强>代码:强>
use strict;
use warnings;
use ARGV::readonly;
while (my $line1 = <>) {
if ($line1 =~ /^\s*(OR|AND)\s*$/) {
my $line2 = <>;
if ($line2 =~ /DATE_SUB/) {
if ($line2 =~ /;\s*$/) {
print ";\n";
}
} else {
print $line1, $line2;
}
} else {
print $line1;
}
}