Tahong Shen
Tahong Shen

Reputation: 101

Unexpected results when using java regex Matcher

The regex pattern in my test program is:

"^#\\{\\S+\\}(:\\$\\{(\\d)\\})+$"

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexPatternTest2 {
    public static void main(String[] args) {
        String line1 = "#{aaa0}:${a22}:${10}";
        String line2 = "#{aaa0}:${0}:${1}";

        String line3 = "#{aaa0}:${a22}:${0}";

        check(line1);
        check(line2);
        check(line3);

    }
    public static void check(String line) {
        System.out.println("========================" + line);

        String keyPattern = "^#\\{\\S+\\}(:\\$\\{(\\d)\\})+$";

        Pattern r1 = Pattern.compile(keyPattern);
        Matcher m1 = r1.matcher(line);
        if(m1.matches()) {
            System.out.println("match line!");
        } else {
            System.out.println("error! can not match line: " + line);
        }
    }
}

I got the output below:

========================#{aaa0}:${a22}:${10}
error! can not match line: #{aaa0}:${a22}:${10}
========================#{aaa0}:${0}:${1}
match line!
========================#{aaa0}:${a22}:${0}
match line!

I expected the Pattern to match the sequence in the String variable line2, but the test result of line3 make me confused.

Upvotes: 1

Views: 64

Answers (2)

fge
fge

Reputation: 121710

The problem is that \S will first swallow everything before giving back.

In your second example, the first part really matches #{aaa0}:${0}, and not #{aaa0} as you suspect.

It therefore stands to reason that the third line matches as well (with the first part matching #{aaa0}:${a22})... You have to replace your \S with something more precise (maybe [^}]?).

Upvotes: 4

Andy Turner
Andy Turner

Reputation: 140328

If you want to match multiple digits, you need to add the + quantifier after your \d:

\\d+

Upvotes: 1

Related Questions