Логический оператор AND с регулярным выражением php

Я бы хотел использовать логический оператор «AND» в моем регулярном выражении. Я попробовал это:

(?=exp1)(?=exp2) 

Но в PHP ?= Не работает и мне нужно написать мою программу на языке PHP. Есть ли другой метод? Выражение должно совпадать, если присутствуют все условия и в любом порядке. Я не хочу писать каждую перестановку вроде:

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

Related of "Логический оператор AND с регулярным выражением php"

PHP поддерживает выражения lookahead. Однако вы, вероятно, не используете их правильно.

Предполагая, что вы хотите совместить строку, содержащую все три из foo , bar и baz , вам нужно регулярное выражение

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

Это вернет совпадение для строк foobarbaz или barbazfoo и т. Д. Однако это совпадение будет пустой строкой (поскольку в 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$ 

спички foobarbaz , foobazbar , barfoobaz , barbazfoo , bazfoobar и bazbarfoo (и ничего больше). «Трюк» вдохновлен замечательной книгой Яна Гойваертса и Стивена Левитана «Поваренная книга регулярных выражений» (стр. 304). Он работает следующим образом:

  • За каждой требуемой частью ( foo и т. Д.) Следует пустая группа захвата () которая всегда совпадает, если соответствующая часть была сопоставлена.
  • Поэтому, если все три необходимые части совпадают, все три пустые группы захвата совпадают.
  • Следующие обратные ссылки будут успешными только в том случае, если каждая из захваченных групп участвовала в матче.
  • Поэтому, если строка является foobarbar , часть (?:foo()|bar()|baz()){3} будет соответствовать, но \3 завершится с ошибкой, поэтому общее регулярное выражение перестанет работать.
  • Если, однако, все трое принимали участие в матче, \1\2\3 удается совместить в конце строки, потому что каждая из групп захвата содержит только пустую строку.

В дополнение к ответу @ Тима:

 (?=exp1)(?=exp2) 

Это никогда не может быть правдой. Вы говорите на простом английском языке: убедитесь, что текст, указанный здесь, является exp1, а также убедитесь, что текст, указанный здесь, – exp2. Ни в коем случае это не так. Он никогда не будет соответствовать.