逻辑运算符AND与php正则表达式

时间:2011-11-22 22:00:56

标签: php regex preg-match logical-operators

我想在我的正则表达式中使用一种逻辑运算符“AND”。 我试过这个:

(?=exp1)(?=exp2)

但是在PHP中?=不起作用,需要用PHP语言编写我的程序。还有另一种方法吗?如果存在所有条件且按任何顺序,则表达式必须匹配。 我不想写每个排列,如:

(exp1)(exp2)(exp3)|(exp1)(exp3)(exp2)|....

2 个答案:

答案 0 :(得分:9)

PHP确实支持超前表达式。但是你可能没有正确使用它们。

假设您要匹配包含所有三个foobarbaz的字符串,则需要正则表达式

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

这将返回字符串foobarbazbarbazfoo等的匹配项。但是,该匹配将是空字符串(因为前瞻不会消耗任何字符)。如果您希望正则表达式返回字符串本身,请使用

^(?=.*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会在字符串末尾成功匹配,因为每个捕获组只包含空字符串。

答案 1 :(得分:1)

除了@Tim的回答:

(?=exp1)(?=exp2)

这永远不会成真。你用简单的英语说:确保这里的文字是exp1,同时确保这里的文字是exp2。这不是真的。它永远不会匹配。