Regex to match anything but two words
Asked Answered
T

3

67

I'm trying to write a regular expression to match anything that isn't "foo" and "bar". I found how to match anything but one word at Regular expression to match a line that doesn't contain a word? but I'm not very skilled with regex and am unsure of how to add a second word to this critera.

Any help would be most appreciated!

CLARIFICATION:

I wanted to match on anything that wasn't EXACTLY foo or bar.

Trefoil answered 26/7, 2011 at 13:33 Comment(2)
is that anything that isn't "foo" or "bar"? Or anything that doesn't contain BOTH "foo" and "bar"?Aerodrome
How do you want to deal with strings that contain one of those two words, along with other characters? For example, should blah blah foo blah blah be allowed?Ringler
V
128

Answer to the question: "A Regular Expression to match anything that isn't "foo" and "bar"?"

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

would do exactly that.

^      # Start of string
(?!    # Assert that it's impossible to match...
 foo   # foo, followed by
 $     # end of string
|      #
 bar$  # bar, followed by end of string.
)      # End of negative lookahead assertion
.*     # Now match anything

You might need to set RegexOptions.Singleline if your string can contain newlines that you also wish to match.

Value answered 26/7, 2011 at 13:35 Comment(2)
This would only fire if the entire string was one of the words. It's not clear whether the OP wants that or not, but it's worth pointing out.Ringler
A great answer to the first "part" of the question: "A regular expression to match anything that is not foo and bar."Ronaronal
R
37

Answer to the question: "How to add a second word to this critera?"

The answer of the question you link to is:

^((?!word).)*$

Where (?!word) is a negative look-ahead. The answer for this question is:

^((?!wordone|wordtwo).)*$

Works for both words. Note: you should enable the global and multiline options, if you have multiple lines and want to match for each line, as the other question.

The difference is the negative look-ahead clause: (?!wordone|wordtwo). It can be extended to any (reasonable) amount of words or clauses.

See this answer for a detailed explanation.

Ronaronal answered 26/7, 2011 at 13:37 Comment(2)
This would fail to match foonly or bartender (or even any word that just contains foo or bar) which is not what goombaloon wants.Value
@Tim Pietzcker: different interpretation. If he meant to extend the answer of the question he refers to, then this works: it will not match anything that contains "foo" or "bar" or both.Ronaronal
R
13

I get what you want to do, but the specifics of what you want to block/allow are a little unclear. For example, do you want to block anything that isn't exactly foo or bar? Or do you want to block anything containing those two strings?

Can they be part of another string, as in @Tim's foonly or bartender examples?

I'm just going to suggest patterns for each one:

/^(?!foo$|bar$).*/   #credit to @Tim Pietzcker for this one, he did it first
    #blocks "foo"
    #blocks "bar"
    #allows "hello goodbye"
    #allows "hello foo goodbye"
    #allows "foogle"
    #allows "foobar"

/^(?!.*foo|.*bar).*$/
    #blocks "foo"
    #blocks "bar"
    #allows "hello goodbye"
    #blocks "hello foo goodbye"
    #blocks "foogle"
    #blocks "foobar"

/^(?!.*\b(foo|bar)\b).*$/
    #blocks "foo"
    #blocks "bar"
    #allows "hello goodbye"
    #blocks "hello foo goodbye"
    #allows "foogle"
    #allows "foobar"
Ringler answered 26/7, 2011 at 13:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.