在阅读this similar question并多次尝试我的代码之后,我继续获得相同的不良输出。
让我们假设我正在搜索的字符串是“我昨天看到了wilma”。 正则表达式应该捕获每个单词后跟一个'a'及其可选 5个字符或空格。
我写的代码如下:
$_ = "I saw wilma yesterday";
if (@m = /(\w+)a(.{5,})?/g){
print "found " . @m . " matches\n";
foreach(@m){
print "\t\"$_\"\n";
}
}
但是,我继续得到以下输出:
found 2 matches
"s"
"w wilma yesterday"
虽然我希望得到以下内容:
found 3 matches:
"saw wil"
"wilma yest"
"yesterday"
直到我发现@m
内的返回值为$1
和$2
,您可以注意到。
现在,由于/g
标志已打开,我认为问题不在于正则表达式,我怎样才能获得所需的输出?
答案 0 :(得分:2)
您可以尝试这种允许重叠结果的模式:
(?=\b(\w+a.{1,5}))
或
(?=(?i)\b([a-z]+a.{0,5}))
示例:
use strict;
my $str = "I saw wilma yesterday";
my @matches = ($str =~ /(?=\b([a-z]+a.{0,5}))/gi);
print join("\n", @matches),"\n";
更多解释:
你不能与正则表达式重叠结果,因为当正则表达式引擎“吃掉”一个字符时,它不能再次被吃掉。避免这种约束的诀窍是使用前瞻(这是一种只检查但不匹配的工具),它可以多次运行字符串,并将捕获组放入其中。
对于此行为的另一个示例,您可以尝试不带字边界(\b
)的示例代码来查看结果。
答案 1 :(得分:1)
首先,您要捕获表达式中的所有内容,即:
/(\w+a(?:.{5,})?)/
接下来,您希望从最后一个表达式的第一个字符匹配的一个字符开始搜索。
pos()
功能可让您指定/g
正则表达式开始搜索的位置。
答案 2 :(得分:1)
$s = "I saw wilma yesterday";
while ($s =~ /(\w+a(.{0,5}))/g){
print "\t\"$1\"\n";
pos($s) = pos($s) - length($2);
}
给你:
"saw wil"
"wilma yest"
"yesterday"
但我不知道为什么你应该day
而不是yesterday
。