繁体   English   中英

如何匹配Perl中特定行上的多个组,而不是其他行?

[英]How to match multiple groups on a specific line in Perl, but not other lines?

我理解/ g标志,我能够多次匹配一个模式,但我很难研究这个特定的问题。

假设我的字符串有多行,我想在包含特定单词的行上匹配分组模式,但不在不同的行上匹配。

对于具有多行的示例字符串$test

Unimportant line.
Important line with !special1! word and !special2! word. 
Extra line with !special3! word and !special4! word.

我想在重要的行上打印两个特价而不是额外的行,所以结果是:

special1, special2  

我可以匹配每个特殊使用/ g

my @both = $test =~ /!(.+?)!/g;
print join(', ', @both);

但输出是:

special1, special2, special3, special4

如果我试着加入'重要'这个词

my @both = $test =~ /Important.+?!(.+?)!/g;
print join(', ', @both);

我得到了

special1

我知道它只匹配一次,因为'重要'只出现一次,但我无法弄清楚如何获得输出

special1, special2

有很多方法可以做到这一点。 我认为最坚实和最灵活的方法是将字符串分解为行并迭代该数组。 然后,您可以在每次迭代时选择如何选择您需要的以及您想要用它做什么。 例如

my @lines = split '\n', $test;

foreach my $line (@lines)
{
    next if $line !~ /^Important/;

    my @all_on_line = $line =~ /!(.+?)!/g;

    if (@all_on_line) 
    {
        print join(', ', @all_on_line), "\n";
    }
}

我认为Important是在想要的线的开头。 根据需要调整。 由于数据可能更多(不仅仅是打印), if条件检查该行是否实际具有该模式。

将它打包成一个正则表达式是相当多的参与。

您可以分两步完成此操作。 首先将重要行与字符串隔离,然后搜索特殊的子字符串

这是一个例子。 它使用for一个topicaliser,并主要在做($_) = $test =~ /^(.*Important.*)$/m为每发生Important

请注意, 如果有多个 数据,此代码将报告 包含“ Important 最后 一行 的数据

use strict;
use warnings 'all';

my $test = <<END;
Unimportant line.
Important line with !special1! word and !special2! word. 
Extra line with !special3! word and !special4! word.
END

my @both;
@both = /!([^!]+)!/g for $test =~ /^(.*Important.*)$/m;

print join(', ', @both), "\n";

产量

special1, special2

这对映射函数也很有用:

my @nwlines = map{ $_=~m/^Important(.+?(?=\!special).+?)$/mi } @lines;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM