微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我有一个巨大的foreach循环,它遍历输出日志并根据匹配的正则表达式提取各种信息.我的主要问题是一些较大类型的输出一个页眉和页脚,如***开始手镯跟踪日志***后跟几行乱码,然后一个***结束手镯跟踪日志***.

有没有办法,从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
    }
}

解决方法

您可以使用 range operator,它在标量上下文中充当触发器:

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

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

if ( $line =~ /Begin .../ .. $line =~ /End .../ ) {

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

if ( ($line =~ /Begin .../) .. ($line =~ /End .../) ) {

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

编辑:根据下面的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...
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐