2014-03-31 95 views
1
perl -ne 'print if /^(?=.*?\bPavel\b)(?=.*?\bDavid\b)((?!Petr|Jan)).*$/' 

輸入:Honza,David,Pavel,Marie,AdamPerl - 爲什麼這個正則表達式匹配?

我認爲它不應該通過,但它確實。

第一個先行應該'消耗'Honza,David,Pavel並且第二個先行應該失敗,因爲在Pavel之後沒有David,或者?

+0

'*'是不貪婪?如果是'。*',那麼它會是貪婪的 –

+0

如果這是你實際需要的行爲,試試類似'\ bPavel(,\ b。* \ b)?, David \ b(?!Petr | Jan) ',可能實際上使用通配符'(?!。* \ b(Petr | Jan))',因爲無論如何它們永遠不可能與'David \ b'相鄰。 – tripleee

+1

@MarcB:貪婪或非貪婪在預測中沒有區別,因爲它們是* zero-width *匹配。 – Borodin

回答

4

第一個預測應該'消耗'Honza,David,Pavel

完全沒有。它被稱爲零寬度積極lookahead因爲它不消耗任何東西。它不會推進下一個原子必須匹配的位置,所以它必須在零位處匹配。


(?!Petr|Jan)不會按原樣工作。它只是檢查它們是否在字符串的開頭。你可以使用

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

這基本上是

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

一個melding這種方法只適用,因爲你正在尋找,直到字符串的結尾。

+0

@aa現在我明白了,ty – Krab

+0

注意ikegami已經移除了無用的'。* $',它永遠不會影響它是否匹配 – ysth

3

獨立lookaheads不「消費」任何東西。這相當於:

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

可以只是簡單:

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