tags:

views:

66

answers:

3

I have the following (Java) code:

public class TestBlah {
    private static final String PATTERN = ".*\\$\\{[.a-zA-Z0-9]+\\}.*";

    public static void main(String[] s) throws IOException {
        String st = "foo ${bar}\n";

        System.out.println(st.matches(PATTERN));
        System.out.println(Pattern.compile(PATTERN).matcher(st).find());
        System.exit(0);
    }
}

Running this code, the former System.out.println outputs false, while the latter outputs true

Am I not understanding something here?

+3  A: 

This is because the . will not match the new line character. Thus, your String that contains a new line, will not match a string that ends with .*. So, when you call matches(), it returns false, because the new line doesn't match.

The second one returns true because it finds a match inside the input string. It doesn't necessarily match the whole string.

From the Pattern javadocs:

. Any character (may or may not match line terminators)

jjnguy
From the same doc: The regular expression . matches any character except a line terminator unless the DOTALL flag is specified.
gawi
+1  A: 

String.matches(..) behaves like Matcher.matches(..). From the documentation of Matcher

find(): Attempts to find the next subsequence of 
        the input sequence that matches the pattern.

matches(): Attempts to match the entire input sequence 
        against the pattern.

So you could think of matches() as if it surrounded your regexp with ^ and $ to make sure the beginning of the string matches the beginning of your regular expression and the end of the string matches the end of the regular expression.

Andre Holzner
A: 

There is a difference between matching a pattern and finding the pattern in a String

  • String.matches() :

    Tells whether or not this string matches the given regular expression.

    Your whole string must match the pattern.

  • Matcher.matches() :

    Attempts to match the entire input sequence against the pattern.

    Again your whole string must match.

  • Matcher.find() :

    Attempts to find the next subsequence of the input sequence that matches the pattern.

    Here you only need a "partial match".


As @Justin said :
Your matches() can't work as the . won't match new line characters (\n, \r and \r\n).


Resources :

Colin Hebert