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