PHP поддерживает прогнозные выражения.Вы, вероятно, используете их неправильно.
Предполагая, что вы хотите сопоставить строку, содержащую все три из foo
, bar
и baz
, вам необходимо регулярное выражение
^(?=.*foo)(?=.*bar)(?=.*baz)
Это вернет совпадение для строк foobarbaz
или barbazfoo
и т. Д. Однако это совпадение будет пустой строкой (потому что просмотрщики не потребляют никаких символов).Если вы хотите, чтобы регулярное выражение возвращало саму строку, используйте
^(?=.*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
успешно сопоставляется в конце строки, поскольку каждая из групп захвата содержит только пустую строку.