TL; DR
MatcherAPI 的设计决策是什么?
背景
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"));
将通话添加到matches()at (2)会将设置Matcher为适当的状态为call group()。
问题,可能不是建设性的
为什么要这样设计该API?为什么用构建时不自动匹配?MatcherPatter.matcher(String)
实际上,你误解了文档。再来看一下你引用的语句:
在成功匹配之前尝试查询它的任何部分都将引发IllegalStateException
。
如果找不到匹配项,则匹配器可能会抛出IllegalStateException
访问错误matcher.group()
。
因此,你需要使用以下测试来实际启动匹配过程:-
- matcher.matches() //Or
- matcher.find()
下面的代码:
Matcher matcher = pattern.matcher();
只需创建一个matcher实例。这实际上不会匹配字符串。即使比赛成功。因此,你需要检查以下情况,以检查是否成功匹配:
if (matcher.matches()) {
// Then use `matcher.group()`
}
而如果在条件if回报false,这意味着什么也没有匹配。因此,如果你在matcher.group()
不检查此条件的情况下使用,将获得IllegalStateException
未找到匹配项的信息。
假设,如果Matcher
按照你所说的方式设计,那么你将必须进行null检查以检查是否找到了匹配项,以致电matcher.group()
,如下所示:
你认为应该完成的方式:
// Suppose this returned the matched string
Matcher matcher = pattern.matcher(s);
// Need to check whether there was actually a match
if (matcher != null) { // Prints only the first match
System.out.println(matcher.group());
}
但是,如果要打印任何其他匹配项,该方法可以在字符串中多次匹配,那么该方法应该告诉匹配器找到下一个匹配项。但是null
支票无法做到这一点。为此,你必须将匹配器向前移动以匹配下一个字符串。因此,在Matcher
类中定义了多种方法来达到目的。该matcher.find()
方法匹配字符串,直到找到所有匹配项。
还有其他方法,即match
字符串以不同的方式取决于你的匹配方式。因此,它最终会在Matcher类上matching针对字符串进行处理。Pattern
类只会创建一个pattern
要匹配的对象。如果Pattern.matcher()
要match
使用模式,则必须有某种方法可以定义to
的各种方法match
,就像matching
可以以不同的方式一样。因此,需要Matcher上课。
因此,实际上是这样的:
Matcher matcher = pattern.matcher(s);
// Finds all the matches until found by moving the `matcher` forward
while(matcher.find()) {
System.out.println(matcher.group());
}
因此,如果在字符串中找到4个匹配项,则第一种方式将仅打印第一个匹配项,而第二种方式将matcher向前移动以匹配下一个模式,从而打印所有匹配项。
我希望这很清楚。
·类的文档描述了它提供的三种方法的用法,它们表示:-
通过调用模式的matcher方法从模式创建匹配器。创建匹配器后,可以使用匹配器执行三种不同类型的匹配操作:
matchs方法尝试将整个输入序列与模式进行匹配。
lookingAt方法尝试将输入序列从开头开始与模式进行匹配。
find方法扫描输入序列以查找与该模式匹配的下一个子序列。
不幸的是,我一直没能找到任何其他官方消息来源,说明确为什么和如何这个问题。
DR 的API背后的设计决策是什么? 此代码引发一个 在。为了解决这个问题,有必要调用或其他方法,使进入允许的状态。以下作品: 在处添加对的调用,可将设置为调用的正确状态。
让我们从Javadocs开始: 非法国家例外 表示在非法或不适当的时间调用了方法。换句话说,Java环境或Java应用程序对于请求的操作没有处于适当的状态。 异常 抛出以指示方法已传递非法或不适当的参数。 上面的问题是,它们非常黑白分明。考虑一个用例,其中方法正在解析调用方提供的文件。该文件存在、可读且格式正确。但是,文件中的某些内容不符合业务规则。在这种情况下,什么是合适的异常抛出-或? 看看提
我试图将一个向量元组转换成一个向量元组(反之亦然)。调用函数时遇到问题。当我用一个参数调用它时,我得到一个错误: prog。cpp:在函数“int main()”中: prog。cpp:44:24:错误:调用“tuple_transpose(std::tuple)”时没有匹配函数 这是一个演示,其中包含错误:http://ideone.com/7AWiQQ#view_edit_box 我做错了什么
当我运行测试用例时,我有以下异常: 测试用例有两个测试,如下所示: 我有两个问题: null 测试毫无问题地通过了.... 编辑4:实际上,我正在拼命地修改下面的示例:https://stackoverflow.com/a/24229350/536299,这是在另一篇文章中给我的。人们会注意到模拟是autowired的,测试确实使用了spring上下文。谁能帮我把考试考对吗?