1

I'm trying to filter files in a folder. I need the files that don't end with ".xml-test". The following regex works as expected (ok1,ok2,ok3 = false, ok4 = true)

String regex = ".+\\.xml\\-test$";
boolean ok1 = Pattern.matches(regex, "database123.xml");
boolean ok2 = Pattern.matches(regex, "database123.sql");
boolean ok3 = Pattern.matches(regex, "log_file012.txt");
boolean ok4 = Pattern.matches(regex, "database.xml-test");

Now I just need to negate it, but it doesn't work for some reason:

String regex = "^(.+\\.xml\\-test)$";

I still get ok1,ok2,ok3 = false, ok4 = true

Any ideas? (As people pointed, this could be done easily without regex. But for arguments sake assume I have to use a single regex pattern and nothing else (ie !Pattern.matches(..); is also not allowed))

3
  • 4
    Why did you think that would negate it? (I think you're mistaking [^stuff] for ^stuff$ Commented Nov 6, 2012 at 15:30
  • 2
    There is no need to use regex for this.. Commented Nov 6, 2012 at 15:31
  • 1
    [^] means negation, only ^ means begin of the string Commented Nov 6, 2012 at 15:31

5 Answers 5

5

I think you are looking for:

if (! someString.endsWith(".xml-test")) {
  ...
}

No regular expression required. Throw this into a FilenameFilter as follows:

public accept(File dir, String name) {
  return ! name.endsWith(".xml-test");
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, but still I was wondering how can I do this with regex. Do you know what my regex should be?
On the basis that you would negate the match, you can search for !Pattern.matches(".+\.xml-test", someString);
I cannot do that, it's a 3rd party library function, gets a regex pattern as argument and returns a list.(it's a bit more complex situation than i posted here)
@Caner: regular expression libraries usually don't support negation as (1) it's extremely expensive, taking exponential time to compile the regex and (2) it interferes with things like capturing and non-regular extensions such as backreferences.
4

The meaning of ^ changes depending on its position in the regexp. When the symbol is inside a character class [] as the first character, it means negation of the character class; when it is outside a character class, it means the beginning of line.

The easiest way to negate a result of a match is to use a positive pattern in regex, and then to add a ! on the Java side to do the negation, like this:

boolean isGoodFile = !Pattern.matches(regex, "database123.xml");

3 Comments

Thanks, but still I was wondering how can I do this with regex. Do you know what my regex should be?
@Caner The closest I was able to get to what you are looking for is this expression: "[^.]+\\.(?!xml-test).*". Here is my link to ideone. However, this will give you some "false negatives" when a string would be disqualified because it has ".xml-test" somewhere in the middle. It passes your tests, though.
ok, I managed to get your version working(changed to this "[^.]+\\.(?!xml-test$).*"), ideone.com/YuhPr0
2

The following Java regex asserts that a string does NOT end with: .xml-test:

String regex = "^(?:(?!\\.xml-test$).)*$";

This regex walks the string one character at a time and asserts that at each and every position the remainder of the string is not .xml-test.

Simple!

Comments

1

^ - is not a negation in regexp, this is a symbol indicating beginning of line you probably need (?!X) X, via zero-width negative lookahead

But I suggest you to use File#listFiles method with FilenameFilter implementation: name.endsWith(".xml-test")

Comments

1

If you really need to test it with regex, then you should use negative lookbehinds from Pattern class:

String reges = "^.*(?<!\\.xml-test)$"

How it works:

  1. first you match whole string: from start (^) all characters (.*),
  2. you check if what have already matched doesn't have ".xml-test" at end (lookbehind at position you already matched),
  3. you test if it's end of string.

1 Comment

This one returns true for all :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.