likejudo
likejudo

Reputation: 3735

Regex negation for a word is not working (Java 7)

I am trying to parse the string returned from a network device to see if there is an error.

The test I am using is if there is no word 'invalid' in the string received, then there is no error. I am unsure if the regex is correct.

Pattern noErrorsPattern = Pattern.compile("^(?!.*(invalid)).*$");   
Matcher noErrorMatcher = noErrorsPattern.matcher(receivedDataString);
if (!noErrorMatcher.matches()) {
    throw new Exception("input has error");
}

receivedDataString does not have the string 'invalid' in it. I checked it by pasting it into an editor and searching for it - it is not found. Yet, stepping through in the debugger, the exception will be thrown.

-- clarification -- I simplified the problem description but that may have misled a bit. Details: For each command, I have a 'FieldPattern' regex to extract data fields from the returned text, and another 'NoError' regex to check if there was an error. The NoError regex can be set precisely for a command like, "new entry added" so that if this string is found, then the operation did succeed. The regex for no occurrence of 'invalid' in the string is the default NoError pattern, if none was specified for the command.

Upvotes: 0

Views: 361

Answers (3)

fge
fge

Reputation: 121840

The problem is that you match multiple lines. And by default, the dot in Java's regular expressions does not match line terminators.

Therefore, you need to specify Pattern.DOTALL when you compile your regular expression.

Note: since your regex is already anchored, you could use .find() instead of .matches(), since the latter will anchor the regex (and one day, you may not want that).

Upvotes: 2

Ted Hopp
Ted Hopp

Reputation: 234857

It seems like your logic is backwards. If the pattern matches, it contains the string "invalid", but you are throwing the exception when the string does not match. (Just calling the pattern noErrorsPattern doesn't make it a no-error pattern :).)

Your regex seems overly complex for the particular case you have posted. How about:

Pattern errorsPattern = Pattern.compile("invalid");   
Matcher errorMatcher = errorsPattern.matcher(receivedDataString);
if (errorMatcher.find()) {
    throw new Exception("input has error");
}

This is equivalent to receivedDataString.contains("invalid"), but allows for more general regex search, which you indicate you need for other cases.

Upvotes: 1

arshajii
arshajii

Reputation: 129572

You don't actually need a regular expression here, you can use the contains method, i.e.

if (receivedDataString.contains("invalid")) {
    throw new Exception("input has error");
}

If you wanted a regex anyway, you could use ".*invalid.*". As mentioned in the comments, if your received string will span multiple lines then be sure to enable the Pattern.DOTALL flag or use instead the regex "(?s).*invalid.*".

Upvotes: 1

Related Questions