tags:

views:

84

answers:

2

Hi,

I need to define a (Java) regex that will match any string that does NOT contain any of these

  • 'foo' or 'foos' as a whole word
  • 'bar' or 'bars' as a whole word
  • 'baz' or 'bazs' as a whole word

Is it possible to express this as a single regex? I know it would be more readable to use 3 separate regexs, but I'd like to do it in one if possible.

Thanks, Don

+2  A: 

Here you go:

^((?!\bfoos?|bars?|bazs?\b).)*$
Rubens Farias
@Rubens: That doesn't quite work... you need an extra bracket around the middle. At the moment, it matches `\bfoos?` or `bars?` or `bazs?\b`.
Paul Wagland
@Paul, I tested that with http://www.radsoftware.com.au/?from=RegexDesigner and ECMAScript, Multiline flags; can you confirm that?
Rubens Farias
scala> "test foobar".matches(".*(?:\\bfoos?|bars?|bazs\\b).*");res17: Boolean = true -- This should return false, since the word foo and the word bar are not in the string. scala> "test foobar".matches(".*(?:\\b(?:foos?|bars?|bazs)\\b).*");res2: Boolean = false -- sorry for the poor formatting, but you can't really format a comment...
Paul Wagland
Oh, and the reason why it won't work? `|` has lower associativity than concatenation, that is the first `\b` binds to the `foos?`, hence you are matching `\bfoos?` or `bars?` or `bazs?\b'. Inserting the extra brackets breaks that up so that you match `\b` followed by (`foos?`, `bars?, or `bazs?`) followed by `\b`
Paul Wagland
+6  A: 

Try the following:

final private static Pattern p = Pattern.compile(".*\\b(?:foos?|bars?|bazs?)\\b.*");
public boolean isGoodString(String stringToTest) {
  return !p.matcher(stringToTest).matches();
}
Paul Wagland