2011-11-22 114 views
5

我想在我的正則表達式中使用一種邏輯運算符「AND」。 我嘗試這樣做:邏輯運算符AND與php正則表達式

(?=exp1)(?=exp2) 

但在PHP ?=不工作,需要在PHP語言編寫程序。有另一種方法嗎?如果存在所有條件並且以任何順序存在,則表達式必須匹配。 我不想寫的每一個排列,如:

(exp1)(exp2)(exp3)|(exp1)(exp3)(exp2)|.... 
+0

我認爲你需要拆分正則表達式 – DiogoDoreto

+4

嗯。 PHP支持'(?= ...)':http://php.net/manual/en/regexp.reference.assertions.php –

回答

9

PHP不支持先行表達式。不過,你可能沒有正確使用它們。

假設你想匹配的是包含所有三個foobarbaz一個字符串,你需要的正則表達式

^(?=.*foo)(?=.*bar)(?=.*baz) 

這將返回匹配的字符串foobarbazbarbazfoo等。然而,那場比賽將是空字符串(因爲這些lookahead不消耗任何字符)。如果你想在正則表達式返回字符串本身,使用

^(?=.*foo)(?=.*bar)(?=.*baz).* 

然後將整個字符串匹配,如果它符合所有三個標準。

我會簡單地使用

if (preg_match('/^(?=.*foo)(?=.*bar)(?=.*baz)/s', $subject)) { 
    # Successful match 
} else { 
    # Match attempt failed 
} 

注意到,這也將匹配字符串喜歡foonly bartender bazooka。如果你不希望這樣(只允許每三個表達式之一的純排列),你可以用一個小竅門做到這一點:

^(?:foo()|bar()|baz()){3}\1\2\3$ 

比賽foobarbazfoobazbarbarfoobazbarbazfoobazfoobarbazbarfoo(沒有別的)。 「訣竅」的靈感來自Jan Goyvaerts和Steven Levithan的優秀書籍"Regular Expressions Cookbook"(第304頁)。它的工作原理如下:

  • 每個所需部分(foo等)之後是一個空的捕獲組()如果所需部分已被匹配,它總是匹配。
  • 因此,如果所有三個必需部分都匹配,則所有三個空捕獲組都匹配。
  • 如果每個捕獲組都參與了匹配,則以下反向引用纔會成功。
  • 所以如果字符串是foobarbar(?:foo()|bar()|baz()){3}部分將會匹配,但\3失敗,所以整體正則表達式失敗。
  • 但是,如果所有三個參與比賽,\1\2\3成功匹配在字符串的末尾,因爲每個捕獲組除了空字符串以外什麼也不包含。
+0

好的,完整的答案。 +1 – FailedDev

+0

@tim你能提供資源或補充嗎?我從來沒見過類似foo()| bar()| baz()的東西。 – bozdoz

+0

我想,我問的是空括號的意義是什麼? – bozdoz

1

除了@添的回答是:

(?=exp1)(?=exp2) 

這不可能是真的。你用簡單的英語說:確保這裏的文字是exp1,並確保這裏的文字是exp2。沒有辦法,這是真的。它永遠不會匹配。