【问题标题】:Java named capture group not found in spite of match尽管匹配,但未找到 Java 命名的捕获组
【发布时间】:2014-12-25 23:55:51
【问题描述】:

我正在尝试使用 Java 的命名捕获组从字符串中提取整数。我知道还有其他更简单的方法可以仅提取数字,但我想使用正则表达式,因为我想确保字符串的其余部分与模式匹配。

line = "Data: 5 Total";
Pattern p = Pattern.compile("(Data: (?<value>\\d+) Total)");
Matcher m = p.matcher(line);
assert m.matches();
String value = m.group("value");

以上代码失败返回,Exception in thread "main" java.lang.IllegalStateException: No match found

唯一被捕获的组是完整的输入字符串"Data: 5 Total"。 为什么内部命名组"value" 未被捕获?

【问题讨论】:

  • 你为什么要使用assert?断言的全部意义在于可以在运行时启用或禁用它们而不更改结果 (ref)。它们不是用于正常的控制流。想一想,你怎么知道它正在捕获完整的输入字符串?如果assert m.matches(); 行没有被执行,m.group() 应该像m.group("value") 一样抛出一个 IllegalStateException。
  • 你是对的。在我写这篇文章的时候,我不明白assert 是如何工作的。我现在已经完全替换了它。
  • @Alan 我现在的理解是,我应该改用 if 语句并在 else 块中抛出异常。这是正确的吗?
  • 您绝对应该使用if 语句,但是如果匹配失败,您应该抛出异常吗?我不知道你的代码是如何被使用的,所以我不能告诉你。

标签: java regex


【解决方案1】:

在尝试访问匹配结果之前,您需要调用find() 以使正则表达式引擎找到其匹配项。您也可以删除整个模式周围的捕获组,并参考 group() 以获取整个匹配项。

String s  = "Data: 5 Total";
Pattern p = Pattern.compile("Data: (?<value>\\d+) Total");
Matcher m = p.matcher(s);
if (m.find()) {
    String value = m.group("value");
    // do something with the match result ...
}

【讨论】:

  • m.matches() 不够用有什么原因吗?我觉得 m.matches() 隐式调用 find()
  • matches() 方法将正则表达式与传递给matcher() 的整个字符串进行匹配。如果正则表达式匹配整个字符串,则 matches() 返回 true。如果不是,则返回 false。
  • 但是如果在matches() 中找到匹配项,那么它不应该也找到其中的组吗?如果字符串是"Data: 5 Total XQWEQWE" 怎么办?在这种情况下,我想收到完整字符串不匹配的通知?我是否需要额外致电matches() 才能完成此操作?
  • 不使用字符串开头 ^ 和字符串结尾 $ 锚点。 ^Data: (?&lt;value&gt;\\d+) Total$
猜你喜欢
  • 1970-01-01
  • 2020-06-08
  • 2017-02-27
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 2020-05-14
相关资源
最近更新 更多