在我们的 Java Selenium 框架中,我们需要编写一个正则表达式来读取任意长度的字符串,并包含子字符串“bar”,只要子字符串“foo”不出现在字符串中,通过结合使用否定查找负向前瞻与负向前瞻。
我能构建的最好的正则表达式是
(?<!foo)bar(?!.*foo).*
它正确匹配以下所需的字符串:
bar
,bar,
,,bar,,
barbar
,bar,bar,
,,bar,,bar,,
barbarbar
,bar,bar,bar,
,,bar,,bar,,bar,,
但是,它也匹配以下不需要的字符串:
,foo,bar,
,,foo,,bar,,
foobarbar
,foo,bar,bar,
,,foo,,bar,,bar,,
,bar,foo,bar,
,,bar,,foo,,bar,,
,foo,foo,bar,
,,foo,,foo,,bar,,
我的测试是在这里进行的:https://regex101.com/r/uhdUhU/5
@CAustin 友善地提供了正确答案:
^(?!.*foo).*(bar).*$
^
在行首声明位置
(?!.*foo)
是负向前瞻
.
匹配任何字符(行终止符除外)
*
匹配前一个令牌,次数为零到无限次,尽可能多的次数,根据需要回馈(贪婪)
$
在行尾声明位置
此处验证的答案:https://regex101.com/r/OzHZ1k/2
这不是我最喜欢的解决方案,但您可以尝试匹配以下正则表达式。
^(?:(?!foo).)*bar(?:(?!foo).)*$
(?:(?!foo).)
匹配任何一个字符,只要该字符与以下两个字符一起(如果存在),请勿拼写 "foo"
。该技术被称为“脾气暴躁的贪婪令牌解决方案”。