让我们考虑一下这个程序:
#!/usr/bin/env perl
use 5.014;
use strict;
use warnings;
my $file = <<END_FILE;
* Action : Lorem ipsum
* Dolor oktam
* Lorem lorem
*
* Input : var1
* var2
* var3
*
* Output : var4
* var5
* var6
END_FILE
$_ = $file;
my ($action, $input) = ('', '');
if (/action\s+:\s*((.|\r\n|\n)*?)(\r\n|\n).*\s*input/gi) {
say "Action: $1";
}
# Not capture anything
if (/input\s+:\s*((.|\r\n|\n)*?)(\r\n|\n).*\s*output/gi) {
say "Input: $1";
}
# But this time it works
if ($file =~ /input\s+:\s*((.|\r\n|\n)*?)(\r\n|\n).*\s*output/gi) {
say "Input OK: $1";
}
# And $_ isn't different from $file
die "WTF!" unless $_ eq $file;
我想在&#34; Action&#34;,&#34;输入&#34;之后提取信息。和&#34;输出&#34;。当我尝试在输入&#34;输入&#34;之后获取信息时,会发生奇怪的事情。如果我使用$_
,则正则表达式不会匹配任何内容,但即使$file
$_ eq $file
也可以使用
我的问题来自哪里?
我得到的输出是:
Action: Lorem ipsum
* Dolor oktam
* Lorem lorem
*
Input OK: var1
* var2
* var3
*
答案 0 :(得分:6)
这是因为您正在使用/g
,这将使下一场比赛尝试在最后一场比赛结束后找到匹配项。由于第一个匹配将使用input
,因此第二个匹配将在input
之后开始,因此永远不会找到另一个匹配的input
。
您可以删除/g
来解决此问题。
perlop会告诉你:
/g
修饰符指定全局模式匹配 - 即匹配 字符串中尽可能多的次数。它的表现取决于 上下文。在列表上下文中,它返回子字符串的列表 与正则表达式中的任何捕获括号匹配。如果 没有括号,它返回所有匹配的列表 字符串,好像整个模式周围都有圆括号。在标量上下文中,
m//g
的每次执行都会找到下一个匹配项,然后返回 如果匹配则为true,如果没有进一步匹配则为false。该 可以使用pos()
读取或设置最后一场比赛后的位置 功能;见pos
。失败的匹配通常会重置搜索位置 到字符串的开头,但你可以通过添加来避免这种情况 / c修饰符(例如,m//gc
)。也修改目标字符串 重置搜索位置