Я пытаюсь выполнить регулярное выражение, которое соответствует, если оба слова кошка И собака находятся в регулярном выражении с поддержкой нескольких строк.
matches
cat asdjfaldsfj dog
####
does NOT match
cat adfasdf8989
####
matches
dog adlsjf88989 cat
####
matches
cat asdf8a89sdf8
a sdf asd f ads f ads fasdf
dog a dsf ads fads f
asdfadsfadsf
Регулярное выражение, которое я использую, довольно простое
/^(?=.*\bcat\b)(?=.*\bdog\b).*$/gs
Проблема в том, что он находит только первое вхождение, так как он жадный. Я действительно хочу, чтобы следующее учитывало два совпадения, но оно соответствует только один раз
cat asdf8a89sdf8
a sdf asd f ads f ads fasdf
dog a dsf ads fads f
asdfadsfadsf
cat asdf8a89sdf8
a sdf asd f ads f ads fasdf
dog a dsf ads fads f
asdfadsfadsf
Даже без второго набора cat STUFF dog STUFF регулярное выражение все еще соответствует до конца.
Некоторые подсказки, но не полный ответ.
.*
с участием /s
собирается съесть все до конца строки. Переход на не жадный .*?
хотя будет соответствовать минимальной строке; опережающие просмотры не включаются в совпадение. Моя обычная стратегия обработки заключается в том, чтобы включить якоря в опережающие просмотры, но многострочное сопоставление затрудняет это.
/m
потребуется, если вы хотите найти несколько раз в одной строке и по-прежнему использовать ^$
якоря. В противном случае они соответствуют только началу и концу строки.
Если вам действительно не нужно решение для общего случая, вероятно, стоит попробовать вручную упорядочить свои подшаблоны, например:
(?gsmx)(?(DEFINE)
(?<a>\bcat\b)
(?<b>\bdog\b)
)
^.*?(?:
(?&a).*?(?&b)| # cat before dog
(?&b).*?(?&a) # dog before cat
)[^\n]*
$
Есть несколько действительно интересных вещей, которые вы можете сделать с рекурсивными подшаблонами и относительными обратными ссылками, но я не смог структурировать их в общий случай для N предпросмотра без увеличения количества шагов до 10k + диапазона.