【发布时间】:2010-09-16 13:01:38
【问题描述】:
我想使用正则表达式(Perl 兼容)能够找到一个被其他两个模式包围的模式,但不包括匹配周围模式的字符串。
例如,我希望能够找到以下字符串的出现:
Foo Bar Baz
但只有匹配包含中间部分:
酒吧
我知道这是可能的,但我不记得该怎么做。
【问题讨论】:
标签: regex
我想使用正则表达式(Perl 兼容)能够找到一个被其他两个模式包围的模式,但不包括匹配周围模式的字符串。
例如,我希望能够找到以下字符串的出现:
Foo Bar Baz
但只有匹配包含中间部分:
酒吧
我知道这是可能的,但我不记得该怎么做。
【问题讨论】:
标签: regex
在一般情况下,您可能不能。最简单的方法是匹配所有内容并使用反向引用来捕获感兴趣的部分:
Foo\s+(Bar)\s+Baz
这与不包括匹配中的周围文本不同。如果您只想提取“Bar”,这可能无关紧要,但如果您多次匹配同一个字符串并且需要从上一个匹配停止的地方继续,这将很重要。
在某些情况下,环顾会起作用。 Tomalak 的建议:
(?<=Foo\s)Bar(?=\sBaz)
仅适用于固定宽度的后视(至少在 Perl 中)。从 Perl 5.10 开始,\K 断言可用于有效地提供可变宽度的后视:
Foo\s+\KBar(?=\s+Baz)
它应该能够在所有情况下执行您要求的操作,但需要您在 Perl 5.10 中实现它。
虽然这很方便,但没有与 \K 等效的方法来结束匹配的文本,因此您必须使用前瞻。
【讨论】:
【讨论】:
$string =~ m/Foo (Bar) Baz/
$1
这可能不是您想要的,因为匹配仍然是“Foo Bar Baz”。但它向您展示了如何只获取您感兴趣的部分。否则您可以使用前瞻和后瞻来获得匹配而不消耗字符...
【讨论】:
括号定义分组。
"Foo (Bar) Baz"
例子
~> cat test.pl
$a = "The Foo Bar Baz was lass";
$a =~ m/Foo (Bar) Baz/;
print $1,"\n";
~> perl test.pl
Bar
【讨论】: