使用Perl捕获输出,直到找到特定模式

Pac*_*man 4 regex perl parsing

我觉得我在这里错过了一些非常简单的东西,但这是我第一次需要这样做而且找不到一个例子.

我有一个巨大的foreach循环,它遍历输出日志并根据匹配的正则表达式提取各种信息.我的主要问题是一些较大类型的输出有一个页眉和页脚,*** Begin bangle tracking log***然后是几行乱码,然后是a ***End bangle tracking log***.

是否有一种方法,从foreach循环内部,有一个内部循环,存储所有行,直到找到页脚?

foreach my $line( @parseme )
{
    if( $line =~ m/***Begin bangle tracking log***/ )
    {
        #Help! Push all lines into an array until bangle tracking footer is found.
    }
    if( $line =~ m/Other stuff I am tracking/ )
    {
        #Do other things
    }
}
Run Code Online (Sandbox Code Playgroud)

Ilm*_*nen 5

您可以使用范围运算符,它在标量上下文中充当触发器:

foreach ( @parseme ) {
    if ( /Begin bangle tracking log/ .. /End bangle tracking log/ ) {
        push @array, $_;
    }
    # other stuff...
}
Run Code Online (Sandbox Code Playgroud)

我用$_foreach循环,因为它允许更简洁的语法.如果您愿意,可以使用另一个变量,但是您必须将条件写为:

if ( $line =~ /Begin .../ .. $line =~ /End .../ ) {
Run Code Online (Sandbox Code Playgroud)

使用一些额外的括号可能更具可读性:

if ( ($line =~ /Begin .../) .. ($line =~ /End .../) ) {
Run Code Online (Sandbox Code Playgroud)

关于触发器操作符需要注意的一个问题是即使在循环结束后它也会记住它的状态.这意味着,如果你打算再次运行循环,你真的应该确保@parseme数组以与正则/End .../表达式匹配的行结束,这样当下一次循环开始时触发器将处于已知状态.

编辑:根据下面的DVK评论,如果您想在到达页脚行时立即处理收集的行,您可以通过检查..运算符的返回值来执行此操作,该值将E0在最后一行结束:

foreach ( @parseme ) {
    my $in_block = /Begin bangle tracking log/ .. /End bangle tracking log/;
    if ( $in_block ) {
        push @array, $_;
    }
    if ( $in_block =~ /E0$/ ) {  # last line
        # process the lines in @array
        @array = ();
    }
    # other stuff...
}
Run Code Online (Sandbox Code Playgroud)