Java正则表达式 – 查找所有匹配项 {…}

huangapple go评论61阅读模式
英文:

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

问题

我无法找出以下代码中的问题所在。
我的目的是找到所有出现在 { } 之间的占位符。

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());

但是如您所见,这段代码会抛出 No match available exception 异常。
正则表达式 \{\w+\} (看起来是)没问题的,在任何在线解析器上尝试,我可以看到 2 处匹配:

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

组详情:
匹配号    组索引    开始索引    结束索引    组内容
1	       0	      6	       12	       {user}
2	       0	      34	       38	       {id}

我需要检索这些组内容,但如您所见,这里没有任何组。我做错了什么?

英文:

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?

答案1

得分: 3

使用while循环替代do-while循环:

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

调用matcher.find()不仅在有另一个匹配项时返回true,还会设置匹配器的状态,将其定位在匹配位置。

do-while循环在执行do块后执行/测试while条件。如果考虑根本没有匹配项会发生什么,就可以明显看出这样做是行不通的。


另外,你可能正在重复造轮子:参见Spring 表达式语言 (SpEL)

英文:

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).

huangapple
  • 本文由 发表于 2020年9月15日 10:59:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/63894428.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定