我对贪婪的操作员的前瞻性和消极前瞻感到困惑。
正向前瞻 的脚本
foreach (<DATA>){
$_ = m/AAA.+(?=BBB)/g;
print "$&\n";
}
__DATA__
AAA 1121 BBB
AAA 443 CCC
AAA 4431 BBB
ABC 321 EACA
AAA 321 BBB
ACD 431 MAKN
AAA 751 ABC
它的输出
AAA 1121
AAA 4431
AAA 321
否定前瞻
foreach (<DATA>){
$_ = m/AAA.+(?!BBB)/g;
print "$&\n";
}
它的输出
AAA 1121 BBB
AAA 443 CCC
AAA 4431 BBB
AAA 321 BBB
AAA 751 ABC
在执行negative lookahed
时,请不要考虑(?!BBB)
。因为我使用了(?!BBB)
之前的贪婪运算符。在这种情况下,前瞻性贪婪算子会考虑(?=BBB)
。这就是为什么给出不同的结果?
我可以通过代码$_ = m/AAA\s\d+(?!.+BBB)/g;
轻松实现OP。
但我不知道代码的执行情况是什么?
答案 0 :(得分:8)
让我们考虑第一个例子:
AAA 1121 BBB
\_/\_______/^
| | |
| | +--- this (the empty string right there) satisfies (?!BBB)
| |
| +-------- matched by .+
|
+-------------- matched by AAA
这是因为贪婪的.+
消费1121 BBB
包括 BBB
。在消耗了剩下的行后,将检查(?!BBB)
对剩余的空字符串。这个空字符串满足(?!BBB)
,因为BBB
后面没有它?
算法执行如下。 ^
是当前位置(字符串中有当前位置,模式中的当前位置 (种类) )
初始状态:
AAA 1121 BBB AAA.+(?!BBB)
^ ^
匹配AAA
AAA 1121 BBB AAA.+(?!BBB)
^ ^
匹配.+
AAA 1121 BBB AAA.+(?!BBB)
^ ^
检查(?!BBB)
AAA 1121 BBB AAA.+(?!BBB)
^ ^
此位置没有BBB
匹配=&gt;成功了!
AAA 1121 BBB
\__________/
现在,让我们看看完全 AAA.+(?=BBB)
产生匹配的原因:
初始状态:
AAA 1121 BBB AAA.+(?=BBB)
^ ^
匹配AAA
AAA 1121 BBB AAA.+(?=BBB)
^ ^
匹配.+
AAA 1121 BBB AAA.+(?=BBB)
^ ^
检查(?=BBB)
AAA 1121 BBB AAA.+(?=BBB)
^ ^
此位置没有BBB
匹配=&gt;回溯(消耗少{char} .+
)
检查(?=BBB)
AAA 1121 BBB AAA.+(?=BBB)
^ ^
此位置没有BBB
匹配=&gt;回溯(消耗少{char} .+
)
检查(?=BBB)
AAA 1121 BBB AAA.+(?=BBB)
^ ^
此位置没有BBB
匹配=&gt;回溯(消耗少{char} .+
)
检查(?=BBB)
AAA 1121 BBB AAA.+(?=BBB)
^ ^
我们在这个位置确实有BBB
个匹配=&gt;成功了!
AAA 1121 BBB
\_______/
答案 1 :(得分:2)
在两种情况下它的工作方式没有区别,.+
在两种情况下都是贪婪的。
将AAA.+(?=BBB)
与AAA 1121 BBB
进行匹配时,.+
AAA
<spc>1121<spc>
之后的(?=BBB)
可以匹配AAA.+(?!BBB)
。任何更长的时间都会导致AAA 1121 BBB
失败。
将.+
与AAA
进行匹配时,<spc>1121<spc>BBB
BBB
(?!BBB)
之后的(?:(?!STRING).)*
可以匹配STRING
。作为字符串的其余部分,它可能不再匹配任何东西。
请注意,字符串的结尾不是[^CHAR]*
,因此CHAR
匹配字符串的末尾。
say $1 if /^(AAA\s+\S+)\s+(?:(?!BBB)\s)*\z/;
是my @F = split;
say "$F[0] $F[1]" if $F[0] eq 'AAA' && $F[2] ne 'BBB';
,{{1}}是{{1}}。
我和
一起去{{1}}
第二个想法,我跟
一起去{{1}}