views:

219

answers:

1

I've searched for questions like this, but all the cases I found were solved in a problem-specific manner, like using !g in vi to negate the regex matches, or matching other things, without a regex negation.

Thus, I'm interested in a “pure” solution to this:

Having a set of strings I need to filter them with a regular expression matcher so that it only leaves (matches) the strings lacking a given substring. For example, filtering out "Foo" in:

Boo
Foo
Bar
FooBar
BooFooBar
Baz

Would result in:

Boo
Bar
Baz

I tried constructing it with negative look aheads/behinds (?!regex)/(?<!regex), but couldn't figure it out. Is that even possible?

+6  A: 

Try this regular expression:

^(?:(?!Foo).)*$

This will consume one character at a time and test if there is no Foo ahead. The same can be done with a negative look-behind:

^(?:.(?<!Foo))*$

But you can also do the same without look-around assertions:

^(?:[^F]*|F(?:$|[^o].|o(?:$|[^o])))*$

This matches any character except F or an F that is either not followed by a o or if followed by an o not followed by another o.

Gumbo
neat (15 chars)
David Hedlund
What does the 2nd ? in ^(?:(?!Foo).)*$ do ?
gameover
Got it its part of : (?<!pattern), +1
gameover
@gameover: It does the same like the first expression but just in the reverse order: Consume one character at a time and test if the last three consumed characters are not *Foo*.
Gumbo