Sandor Mezil
Sandor Mezil

Reputation: 391

Java Regex - Lookup all matches of {...}

I can't find out what's wrong in the following code. My purpose is to find all occurences of placeholders between { }.

String template = "Hello {user}, your  request id is {id}.";
String PH_PATTERN = "\\{\\w+\\}";
Pattern pattern = Pattern.compile(PH_PATTERN);
Matcher matcher = pattern.matcher(template);

System.out.println(matcher.groupCount());     // >0
System.out.println(matcher.find());           // >true
System.out.println(matcher.matches());        // >false

do {
    System.out.println("Start:" + matcher.start() + ", end:" + matcher.end());
    // Throws: Exception in thread "main" java.lang.IllegalStateException: No match available
} while (matcher.find());

But as you can see this code throws a No match available exception. The regular expression \{\w+\} is (seems to be) OK, trying any online parser I see the 2 matches:

Hello {user}, your request id is {id}.

Group details:
Match # Group index Start index End index   Group content
1       0           6            12         {user}
2       0           34           38         {id}

I need to retrieve those group contents, but as you can see there are no groups there. What am I doing wrong?

Upvotes: 0

Views: 84

Answers (1)

Bohemian
Bohemian

Reputation: 425348

Use a while loop instead of a do-while loop:

while (matcher.find()) {
    System.out.println("Start:" + matcher.start() + ", end:" + matcher.end());
} 

Calling matcher.find() not only returns true if there's another match, but sets the state of the matcher to position it at the match.

A do-while loop executes/tests the while condition after the do block is executed. It's obvious how this wouldn't work if you consider what would happen if there were no matches at all.


As an aside, you may be reinventing the wheel: See Spring Expression Language (SpEL).

Upvotes: 3

Related Questions