Я пытаюсь выполнить regex, который соответствует, если оба слова cat И dog находятся в regex с многострочной поддержкой
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
Regex, который я использую, довольно прост
/^(?=.*\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 regex все равно находит совпадение до конца.
Некоторые подсказки, но не полный ответ.
. *
with / s
съест все до конца строки. Переход на не жадный . *?
, хотя будет соответствовать минимальной строке; опережающие просмотры не включаются в совпадение. Моя обычная стратегия обработки заключается в том, чтобы включать якоря в предварительные просмотры, но многострочное сопоставление затрудняет это.
/ m
потребуется, если вы хотите сопоставить несколько раз в одной строке и по-прежнему использовать ^ $
якоря. В противном случае они соответствуют только началу и концу строки.
Если вам действительно не нужно решение для общего случая, вероятно, стоит попробовать его вручную, упорядочивая свои подшаблоны, например:
(?gsmx)(?(DEFINE)
(?<a>\bcat\b)
(?<b>\bdog\b)
)
^.*?(?:
(?&a).*?(?&b)| # cat before dog
(?&b).*?(?&a) # dog before cat
)[^\n]*
$
Есть несколько действительно интересных вещей, которые вы можете сделать с рекурсивными подшаблонами и относительные обратные ссылки, но я не смог структурировать их в общий случай для N просмотров вперед без увеличения числа шагов до 10k +.