如何编写将负面展望与负面展望相结合的正则表达式以创建负面展望?

How do you write a Regex that combines a Negative Lookbehind with a Negative Lookahead to create a Negative Lookaround?

提问人:RobbieDixonBr-dge 提问时间:11/10/2023 最后编辑:RobbieDixonBr-dge 更新时间:11/11/2023 访问量:79

问:

在我们的 Java Selenium 框架中,我们需要编写一个正则表达式,该正则表达式读取任何长度的字符串,如果它包含子字符串 “bar”,则返回 true,只要子字符串 “foo” 没有出现在字符串中,方法是将 Negative Lookbehind 与 Negative Lookahead 相结合。

我能构造的最好的正则表达式是(?<!foo)bar(?!.*foo).*

它正确匹配以下所需的字符串:

  1. bar

  2. ,bar,

  3. ,,bar,,

  4. barbar

  5. ,bar,bar,

  6. ,,bar,,bar,,

  7. barbarbar

  8. ,bar,bar,bar,

  9. ,,bar,,bar,,bar,,

但是,它还匹配以下不需要的字符串:

  1. ,foo,bar,

  2. ,,foo,,bar,,

  3. foobarbar

  4. ,foo,bar,bar,

  5. ,,foo,,bar,,bar,,

  6. ,bar,foo,bar,

  7. ,,bar,,foo,,bar,,

  8. ,foo,foo,bar,

  9. ,,foo,,foo,,bar,,

我的测试是在这里进行的:https://regex101.com/r/uhdUhU/5

java 正则表达式 lookarounds 否定 正则表达式 look-ahead

评论

0赞 trincot 11/10/2023
你写的它应该与子字符串栏匹配,但在你的可写字符串列表中,有包含逗号的匹配项。你能澄清一下吗?您想对整个输入字符串进行是/否测试吗?
2赞 CAustin 11/10/2023
很难用火柴来做,用捕捉很容易。查看 regex101.com/r/OzHZ1k/1
1赞 The fourth bird 11/10/2023
如果要在 Java 中单独匹配,请参阅 regex101.com/r/cIl6tC/1(?<!foo.{0,1000})bar(?!.*foo)
0赞 RobbieDixonBr-dge 11/10/2023
对不起,我的意思是包含不匹配 - 术语从来都不是我的强项
0赞 RobbieDixonBr-dge 11/10/2023
@CAustin太棒了,简直太棒了!这是我明天去度假前的最后一天,这篇文章是最后的机会。现在将更新答案!

答:

2赞 RobbieDixonBr-dge 11/10/2023 #1

@CAustin和@CarySwoveland提供了正确的答案:^(?!.*foo).*bar

^在行首处断言位置

(?!.*foo)是负面展望

.匹配任何字符(行终止符除外)

*在零到无限次之间匹配前一个代币,尽可能多地,根据需要回馈(贪婪)

答案已验证: https://regex101.com/r/OzHZ1k/3

评论

0赞 Cary Swoveland 11/11/2023
罗比,看到谢谢你对答案提出改进建议并不罕见,但将来可以考虑将它们放在评论中,以保持答案“干净”。当然,这只是我个人的喜好,并不是什么大问题。请注意,许多成员并不期望得到感谢。@CAustin,我删除了上面的评论,因为它不再相关,并且也将很快删除此评论。您也可以考虑删除您的评论。
2赞 Cary Swoveland 11/10/2023 #2

这不是我的首选解决方案,但您可以尝试匹配以下正则表达式。

 ^(?:(?!foo).)*bar(?:(?!foo).)*$

演示

(?:(?!foo).)匹配任何一个字符,前提是该字符与以下两个字符(如果存在)一起拼写 。该技术被称为“脾气暴躁的贪婪代币解决方案”。"foo"