Perl - 为什么这个正则表达式匹配?

时间:2014-03-31 19:13:18

标签: regex perl

perl -ne 'print if /^(?=.*?\bPavel\b)(?=.*?\bDavid\b)((?!Petr|Jan)).*$/'

输入: Honza,David,Pavel,Marie,Adam

我认为它不应该通过,但确实如此。

第一个前瞻应该消费' Honza,David,Pavel和第二个预测会失败,因为David之后没有Pavel,或者?

2 个答案:

答案 0 :(得分:4)

  

第一个前瞻应该消费' Honza,David,Pavel

完全没有。它被称为零宽度正向前瞻,因为它不会消耗任何东西。它不会提升下一个原子必须匹配的位置,因此它也必须在零位置匹配。


但是,

(?!Petr|Jan)不会按原样运作。它只是检查它们是否在字符串的开头。你可以用

/^(?=.*\bPavel\b)(?=.*\bDavid\b)(?!.*\b(?:Petr|Jan)\b)/x

基本上是

的融合
/\bPavel\b/ && /bDavid\b/ && !/\b(?:Petr|Jan)\b/

此方法仅适用,因为您正在查看字符串的结尾。

答案 1 :(得分:3)

独立前瞻不会“消耗”任何东西。这相当于:

print if /^(?=.*?\bPavel\b)/ && /^(?=.*?\bDavid\b)/ && /^((?!Petr|Jan))/'

可以简化为:

perl -ne 'print if /\bPavel\b/ && /\bDavid\b/ && /^((?!Petr|Jan))/'