1

I thought I knew a thing or two... then I met RegEx. So what I am trying to do is a multistring negative look-ahead? Is that a thing? Basically I want to find when a 3rd string exists BUT two precursory strings do NOT.

(?i:<!((yellow thing)\s(w+\s+){0,20}(blue thing))\s(\w+\s+){0,100}(green thing))

Target String:

  • Here we have a yellow thing. Here we have a blue thing. Clearly the green thing is best though. (Should NOT match)
  • You wanna buy some death sticks? I have a green thing. (MATCH)
  • We are on a yellow thing submarine? Look at that green thing over there! (MATCH)
Brenticus
  • 9
  • 3

2 Answers2

0

Try this:

^(?:(?!\byellow thing\b.*?\bblue thing\b).)*\bgreen thing\b

Demo: https://regex101.com/r/dL0uZ1/2

Explanation:

  • look for the "green thing" (\b's around it mark word boundaries)
  • but only if it is not preceded by the two other strings as seen from the beginning of the text line hence ^ followed by the "string not containing a pattern" pattern (see Regular expression to match a line that doesn't contain a word? for more details on it).
Community
  • 1
  • 1
Dmitry Egorov
  • 9,337
  • 3
  • 23
  • 39
0

I understand the question as an attempt to only match c inside the string, not the whole string, using the negative lookbehind of infinite width.

You spoiled the lookbehind structure by inserting i: right after ?, and you missed the fact that there can be non-word characters in-between "words".

Thus, you need

(?<!yellow thing\W*(?:\w+\W+){0,20}\W*blue thing\W*(?:\w+\W+){0,100})green thing

See the regex demo where I added numbers to emulate the number of optional words in-between matches.

NOTE: You may add word boundaries around things to match them as whole words only - that depends on your requirements.

Also, you may turn all capturing groups (\w+\W+) into non-capturing to keep these group stacks free (no need to keep track of what these groups capture, right?) If you need to capture them, keep capture groups intact.

Results:

enter image description here

Wiktor Stribiżew
  • 561,645
  • 34
  • 376
  • 476