如何编写将负向后查找与负向前查找相结合的正则表达式来创建负查找?

问题描述 投票:0回答:2

在我们的 Java Selenium 框架中,我们需要编写一个正则表达式来读取任意长度的字符串,并包含子字符串“bar”,只要子字符串“foo”不出现在字符串中,通过结合使用否定查找负向前瞻与负向前瞻。

我能构建的最好的正则表达式是

(?<!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 regex regex-lookarounds regex-negation regex-look-ahead
2个回答
0
投票

@CAustin 友善地提供了正确答案:

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

^
在行首声明位置

(?!.*foo)
是负向前瞻

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

*
匹配前一个令牌,次数为零到无限次,尽可能多的次数,根据需要回馈(贪婪)

$
在行尾声明位置

此处验证的答案:https://regex101.com/r/OzHZ1k/2


0
投票

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

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

演示

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

© www.soinside.com 2019 - 2024. All rights reserved.