【发布时间】:2012-10-06 08:44:38
【问题描述】:
TL;DR
Matcher 的 API 背后的设计决策是什么?
背景
Matcher 的行为出乎我的意料,而且我找不到很好的理由。 API 文档说:
创建后,匹配器可用于执行三种不同类型的匹配操作: [...] 这些方法中的每一个都返回一个指示成功或失败的布尔值。更多关于匹配成功的信息可以通过查询匹配器的状态来获得。
API 文档进一步说明的是:
匹配器的显式状态最初是未定义的;在成功匹配之前尝试查询它的任何部分将导致抛出 IllegalStateException。
示例
String s = "foo=23,bar=42";
Pattern p = Pattern.compile("foo=(?<foo>[0-9]*),bar=(?<bar>[0-9]*)");
Matcher matcher = p.matcher(s);
System.out.println(matcher.group("foo")); // (1)
System.out.println(matcher.group("bar"));
这段代码抛出一个
java.lang.IllegalStateException: No match found
(1)。为了解决这个问题,有必要调用matches() 或其他将Matcher 带入允许group() 的状态的方法。以下作品:
String s = "foo=23,bar=42";
Pattern p = Pattern.compile("foo=(?<foo>[0-9]*),bar=(?<bar>[0-9]*)");
Matcher matcher = p.matcher(s);
matcher.matches(); // (2)
System.out.println(matcher.group("foo"));
System.out.println(matcher.group("bar"));
在(2) 处添加对matches() 的调用会将Matcher 设置为调用group() 的正确状态。
问题,可能没有建设性
为什么这个 API 是这样设计的?当Matcher 是用Patter.matcher(String) 构建时,为什么不自动 匹配?
【问题讨论】:
-
有趣。即使在问题、答案和赏金解决几周后,人们仍然认为这个问题值得一票否决。
-
我发现这是一个糟糕的 API 设计 - 有点相当于在构建后需要一种“initialize()”。在某些合法情况下,您可以知道给定的 Matcher 已经匹配给定的字符串。
-
@Ben 我在框架中见过的最糟糕的 API 设计!非常不直观,带有无用的无用错误消息:-(
标签: java regex illegalstateexception