perl -ne 'print if /^(?=.*?\bPavel\b)(?=.*?\bDavid\b)((?!Petr|Jan)).*$/'
输入:Honza,David,Pavel,Marie,Adam
Perl - 为什么这个正则表达式匹配?
我认为它不应该通过,但它确实。
第一个先行应该'消耗'Honza,David,Pavel
并且第二个先行应该失败,因为在Pavel
之后没有David
,或者?
perl -ne 'print if /^(?=.*?\bPavel\b)(?=.*?\bDavid\b)((?!Petr|Jan)).*$/'
输入:Honza,David,Pavel,Marie,Adam
Perl - 为什么这个正则表达式匹配?
我认为它不应该通过,但它确实。
第一个先行应该'消耗'Honza,David,Pavel
并且第二个先行应该失败,因为在Pavel
之后没有David
,或者?
第一个预测应该'消耗'
Honza,David,Pavel
。
完全没有。它被称为零宽度积极lookahead因为它不消耗任何东西。它不会推进下一个原子必须匹配的位置,所以它必须在零位处匹配。
(?!Petr|Jan)
不会按原样工作。它只是检查它们是否在字符串的开头。你可以使用
/^(?=.*\bPavel\b)(?=.*\bDavid\b)(?!.*\b(?:Petr|Jan)\b)/x
这基本上是
/\bPavel\b/ && /bDavid\b/ && !/\b(?:Petr|Jan)\b/
一个melding这种方法只适用,因为你正在寻找,直到字符串的结尾。
独立lookaheads不“消费”任何东西。这相当于:
print if /^(?=.*?\bPavel\b)/ && /^(?=.*?\bDavid\b)/ && /^((?!Petr|Jan))/'
可以只是简单:
perl -ne 'print if /\bPavel\b/ && /\bDavid\b/ && /^((?!Petr|Jan))/'
'*'是不贪婪?如果是'。*',那么它会是贪婪的 –
如果这是你实际需要的行为,试试类似'\ bPavel(,\ b。* \ b)?, David \ b(?!Petr | Jan) ',可能实际上使用通配符'(?!。* \ b(Petr | Jan))',因为无论如何它们永远不可能与'David \ b'相邻。 – tripleee
@MarcB:贪婪或非贪婪在预测中没有区别,因为它们是* zero-width *匹配。 – Borodin