从Perl脚本中省略或排除正则表达式匹配

时间:2009-11-25 22:29:47

标签: regex perl

您好我想在文件中搜索与此类似的内容:

Start Cycle
report 1
report 2
report 3
report 4
End Cycle

....继续......

我想搜索“Start Cycle”,然后从中提取报告1并报告3 ..我的正则表达式看起来像这样

(Start Cycle .*\n)(.*\n)(.*\n)(.*\n)

上面的正则表达式选择Start Cycle和接下来的三行..但是我想从结果中省略thrid行。那可能吗?或者任何更简单的perl脚本都可以完成? 我期待的结果如下:

Start Cycle
report 1
report 3

8 个答案:

答案 0 :(得分:5)

以下代码打印Start CycleEnd Cycle之间的奇数行:

foreach (<$filehandle>) {
    if (/Start Cycle/ .. /End Cycle/) {
        print if /report (\d+)/ and $1 % 2;
    }
}

答案 1 :(得分:2)

您可以在开始和结束标记之间找到文本,然后按行分割上下文。这是一个例子:

my $text = <<TEXT;
Start Cycle
report 1
report 2
report 3
report 4
End Cycle
TEXT

## find text between all start/end pairs
while ($text =~ m/^Start Cycle$(.*?)^End Cycle$/msg) {
    my $reports_text = $1;
    ## remove leading spaces
    $reports_text =~ s/^\s+//;
    ## split text by newlines
    my @report_parts = split(/\r?\n/m, $reports_text);
}

答案 2 :(得分:2)

也许这是一种疯狂的方式:改变Perl对输入记录的理解。

$/ = "End Cycle\n";
print( (/(.+\n)/g)[0,1,3] ) while <$file_handle>;

答案 3 :(得分:1)

正则表达式使用每对括号的内容填充1美元,2美元,3美元和4美元。

因此,如果你只看$ 1,$ 2和$ 4的内容就可以得到你想要的东西。

或者你也可以不用第三行的括号。

你的正则表达式应该类似于

/Start Cycle\n(.+)\n.+\n(.+)\n.+\nEnd Cycle/g

/ g将允许您重复评估正则表达式,并且每次都能获得下一个匹配。

答案 4 :(得分:1)

如果你想让所有周围的代码保持不变但是停止捕获第三件事,你可以简单地删除导致该行捕获的parens:

(Start Cycle .*\n)(.*\n).*\n(.*\n)

答案 5 :(得分:1)

我将OP的问题作为Perl练习,并提出以下代码。它只是为了学习目的而编写的。如果有什么看起来很可疑,请向我纠正。

while(<>) {
   if(/Start Cycle/) {
        push @block,$_;
        push @block, scalar<> for 1..3;               
        print @block[0,1,3];
        @block=(); 
           }
        }

另一个版本(编辑并感谢,@ FM):

local $/;
$_ = <>;
  @block = (/(Start Cycle\n)(.+\n).+\n(.+\n)/g);
  print @block;

答案 6 :(得分:0)

更新:我最初没有注意到这只是@FM's answer,只是稍微强一些,而且形式更长。

#!/usr/bin/perl

use strict; use warnings;

{
    local $/ = "End Cycle\n";
    while ( my $block = <DATA> ) {
        last unless my ($heading) = $block =~ /^(Start Cycle\n)/g;
        print $heading, ($block =~ /([^\n]+\n)/g)[1, 3];
    }
}

__DATA__
Start Cycle
report 1
report 2
report 3
report 4
End Cycle

输出:

Start Cycle
report 1
report 3

答案 7 :(得分:0)

while (<>) {
    if (/Start Cycle/) {
        print $_;
        $_ = <>;
        print $_;
        $_ = <>; $_ = <>;
        print $_;
    }
}