如何匹配单词后跟新行,然后抓住下一行到新行?

时间:2011-07-22 23:21:31

标签: regex perl

我正在编辑一堆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”和它的行,同时离开最后的“;”。

3 个答案:

答案 0 :(得分:3)

$sql =~ s/\b(?:OR|AND)[ \t]*[\n\r]+(?=.*DATE).*(?<![;\s])//mg;

删除OR(或AND)以及以下行中的内容(如果其中包含DATE),但可能的结尾;除外。

注意这样的简单正则表达式不适用于您更新的示例,因为删除的行上有右括号,属于其他行。

http://ideone.com/0Lbxp

的示例

答案 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;
    }
}