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

101 views Asked by At

In our Java Selenium framework, we need to write a regex that reads a string of any length and returns true if it contains the substring "bar" so long as the substring "foo" doesn't appear in the string by using a Negative Lookaround by combining a Negative Lookbehind with a Negative Lookahead.

The best regex I can construct is (?<!foo)bar(?!.*foo).*

It correctly matches the following desirable strings:

  1. bar

  2. ,bar,

  3. ,,bar,,

  4. barbar

  5. ,bar,bar,

  6. ,,bar,,bar,,

  7. barbarbar

  8. ,bar,bar,bar,

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

However, it also matches the following undesirable strings:

  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,,

My testing was conducted here: https://regex101.com/r/uhdUhU/5

2

There are 2 answers

1
RobbieDixonBr-dge On BEST ANSWER

@CAustin and @CarySwoveland have kindly provided the right answer: ^(?!.*foo).*bar

^ asserts position at start of a line

(?!.*foo) is the Negative Lookahead

. matches any character (except for line terminators)

* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)

Answer verified here: https://regex101.com/r/OzHZ1k/3

0
Cary Swoveland On

It would not be my preferred solution, but you could attempt to match the following regular expression.

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

Demo

(?:(?!foo).) matches any one character provided that character together with the two following, if present, do not spell "foo". The technique is called "tempered greedy token solution".