tags:

views:

908

answers:

5

With PCRE, how can you construct an expression that will only match if a string is not found.

If I were using grep (which I'm not) I would want the -v option.

A more concrete example: I want my regexp to match iff string foo is not in the string. So it would match bar would but not foobar.

A: 

It's indeed almost a duplicate. I guess the regex you're looking for is

(?!foo).*

Philippe Leybaert
+1  A: 

Based on Daniel's answer, I think I've got something that works:

^(.(?!test))*$

The key is that you need to make the negative assertion on every character in the string

Joe Beda
I don't believe this will work either; it will match the string 'test'.
Daniel Vandersluis
Shoot -- you are right. This is good enough for my current scenario as that edge case doesn't hit, but it doesn't completely solve the problem.
Joe Beda
I deleted my original answer and posted a new one which should solve the problem completely, including the edge case. Basically my original answer denied strings starting with your substring, and yours denied strings containing the substring but not starting with it. Putting them together is the solution. :)
Daniel Vandersluis
A: 

Build an expression that matches, and use !match()... (logical negation) That's probably how grep does anyway...

PhiLho
I don't have control over the code that evaluates the match directly so this, unfortunately, isn't an option.
Joe Beda
+4  A: 

Okay, I have refined my regular expression based on the solution you came up with (which erroneously matches strings that start with 'test').

^((?!foo).)*$

This regular expression will match only strings that do not contain foo. The first lookahead will deny strings beginning with 'foo', and the second will make sure that foo isn't found elsewhere in the string.

Daniel Vandersluis
I've been playing around and I think it can be shortened to ^((?!foo).)*$. Since it is a lookhead assertion, we don't have to worry about the case where the current matching point is at the end.
Joe Beda
You're right, that is cleaner.
Daniel Vandersluis
+2  A: 

I already answered this question for someone, see these links:

musicfreak