views:

85

answers:

3

Example:

Suppose in the following example I want to match strings that do not contain the word "NOOOT".
Example A: This shirt is NOOOT black.
Example B: This shirt is black.

I want something a little bit like the like the non-matching character class (e.g. [^abc]), but for whole strings:
.*?(^NOOOT).*?

Does such a creature exist?

+3  A: 
^(?:(?!NOOOT).)*$

Explanation:

^ start of string

(?!NOOOT). assert that it's not possible to match NOOOT at the current position, then match any character.

(?: ...)* do this any number of times until...

$ end of string.

Tim Pietzcker
Awesome Tim, thanks. Here, have a tick. It was a tough one between Gumbo and you both posting the same answer at the SAME TIME so I couldn't even do it on who got there first. In the end, your extra explanation helped. Thanks :)
Iain Fraser
+3  A: 

You can do that wit a negative lookahead assertion (?!…):

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

This one matches only if there is no NOOOT ahead at the current position while proceeding character by character.

It’s also possible to do that with basic syntax. But that’s more complex.

Gumbo
Thanks for the awesome answer Gumbo. The tick was a tough choice as you both answered at the same time. In the end I gave it to Tim just because he added a bit more of an explanation. But if I could give out two, I've give you one too. Cheer mate ;)
Iain Fraser
+2  A: 

Complementing regexes is a bad idea. It's possible but really bad style, and may be inefficient; and the negative assertions that allow you to do it concisely may only hide the inefficiency. Almost always the better idea is to match the regexp normally and invert the result with !.

You should only ever compose negative regexes if you absolutely have to, e.g. if you must satisfy an API that can only be programmed by supplying one regext and nothing else.

Kilian Foth
In this situation it's all good though because I'm just using it to process one really long document I've been given. It's a one-off, it will never see a production environment ;)
Iain Fraser