多行PCRE w \ lookhead,计数匹配

我试图执行一个正则expression式匹配,如果这两个字猫和狗都在正则expression式与多线支持

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 

我使用的正则expression式非常简单

 /^(?=.*\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 

即使没有第二组猫STUFF狗STUFF正则expression式仍然匹配,直到结束。

一些提示,但不是一个完整的答案。

.*/s是要吃的一切,直到string结束。 切换到非贪心.*? 虽然会匹配一个最小的string; 前瞻不会被迫进入比赛。 我通常的处理策略是在预见中包含锚点,但是多行匹配使得这很困难。

/m将是必需的,如果你想在同一个string中多次匹配,仍然使用^$锚。 否则,它们只匹配string的开头和结尾。

除非你真的需要一个通用的解决scheme,否则可能值得尝试一个手动sorting你的子模式,例如:

 (?gsmx)(?(DEFINE) (?<a>\bcat\b) (?<b>\bdog\b) ) ^.*?(?: (?&a).*?(?&b)| # cat before dog (?&b).*?(?&a) # dog before cat )[^\n]* $ 

使用recursion子模式和相对的反向引用可以做一些非常有趣的事情,但是我不能将它们构造成N向量的一般情况,而没有步骤数量在10k +范围内飙升。