我正在尝试执行一个正则表达式,如果单词 cat 和 dog 都在正则表达式中并且支持多行,则该正则表达式匹配
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,正则表达式仍然匹配直到最后。
答案1
有一些提示,但不是完整的答案。
.*
with/s
会吃掉所有东西直到字符串结束。.*?
但是切换到非贪婪模式会匹配最小字符串;前瞻不会被强制纳入匹配。我通常的处理策略是在前瞻中包含锚点,但多行匹配会让这变得困难。
/m
如果您想在同一个字符串中多次匹配并且仍然使用锚点,则需要使用^$
。否则它们仅匹配字符串的开头和结尾。
除非您确实需要一般情况的解决方案,否则可能值得尝试手动排序子模式,例如:
(?gsmx)(?(DEFINE)
(?<a>\bcat\b)
(?<b>\bdog\b)
)
^.*?(?:
(?&a).*?(?&b)| # cat before dog
(?&b).*?(?&a) # dog before cat
)[^\n]*
$
使用递归子模式和相对反向引用可以做一些非常有趣的事情,但是我无法将它们构建为 N 前瞻的一般情况,因为步骤数不会飙升到 10k+ 范围。