匹配未用括号括起来的文本 [英] Matching text not enclosed by parenthesis
问题描述
我仍在学习 Perl,如果这是一个明显的问题,我深表歉意.有没有办法匹配没有括号括起来的文本?例如,搜索 foo 只会匹配第二行.
I am still learning Perl, so apologies if this is an obvious question. Is there a way to match text that is NOT enclosed by parenthesis? For example, searching for foo would match the second line only.
(bar foo bar)
bar foo (
bar foo
(bar) (foo)
)
推荐答案
这离显而易见"还很远;相反.对于复杂的模式,没有直接的方法说不匹配"(在字符级别有很好的支持,例如 [^a]
、\S
等).正则表达式首先是关于匹配事物,而不是不匹配它们.
This is very far from "obvious"; on the contrary. There is no direct way to say "don't match" for a complex pattern (there is good support at a character level, with [^a]
, \S
etc). Regex is firstly about matching things, not about not-matching them.
一种方法是匹配那些(可能是嵌套的)分隔符并获取除此之外的所有内容.
One approach is to match those (possibly nested) delimiters and get everything other than that.
查找嵌套分隔符的好工具是核心模块 Text::Balanced.当它匹配时,它还可以为我们提供匹配之前的子字符串和匹配之后的字符串的其余部分.
A good tool for finding nested delimiters is the core module Text::Balanced. As it matches it can also give us the substring before the match and the rest of the string after the match.
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
);所以我们继续匹配余数.
The extract_bracketed
returns the match, the remainder substring ($remainder
), and the substring before the match ($before
); so we keep matching in the remainder.
取自这篇文章,其中有更多详细信息和另一种方式,使用 Regexp::Common.
Taken from this post, where there are more details and another way, using Regexp::Common.
这篇关于匹配未用括号括起来的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!