匹配的文本没有括号括起来

时间:2017-12-12 17:55:22

标签: perl parentheses

我还在学习Perl,如果这是一个显而易见的问题,请道歉。 有没有办法匹配括号内未包含的文本? 例如,搜索foo只会匹配第二行。

(bar foo bar)
bar foo (
bar foo 
   (bar) (foo)
)

2 个答案:

答案 0 :(得分:5)

正则表达式模式具有隐式前导\G(?s:.)*?("跳过字符直到找到匹配")。以下内容扩展了该定义,以将嵌套的parens视为要跳过的字符。

while (
   $string =~ m{
      \G (?&MEGA_DOT)*?

      ( foo )

      (?(DEFINE)
         (?<MEGA_DOT> [^()] | \( (?&MEGA_DOT)*+ \) )
      )
   }xg
) {
   say "Found a match at pos $-[1].";
}

答案 1 :(得分:4)

这离&#34;很明显&#34 ;;反之。没有直接的方式可以说'#34;不匹配&#34;对于复杂的模式(在角色级别有良好的支持,[^a]\S等)。正则表达式首先是关于匹配事物,而不是关于不匹配它们。

一种方法是匹配那些(可能是嵌套的)分隔符并获得除此之外的所有内容。

查找嵌套分隔符的好工具是核心模块Text::Balanced。在匹配时,它还可以在匹配之前为我们提供子字符串,在匹配之后为字符串的其余部分提供。

use warnings;
use strict;
use feature 'say';

use Text::Balanced qw(extract_bracketed);

my $text = <<'END';
(bar foo bar)
bar foo (
bar foo 
   (bar) (foo)
   )
END

my ($match, $before);
my $remainder = $text;
while (1) {
    ($match, $remainder, $before) = extract_bracketed($remainder, '(', '[^(]*');
    print $before // $remainder;
    last if not defined $match; 
}

extract_bracketed返回匹配,余数子串($remainder)和匹配前的子字符串($before);所以我们在其余部分保持匹配。

取自this post,其中有更多详情和其他方式,使用Regexp::Common