2014-10-30 40 views
0

我正尝试使用Java的命名捕获组来从字符串中提取整数。我知道还有其他更简单的方法来提取数字,但我想使用正则表达式,因为我想确保字符串的其余部分与模式匹配。尽管匹配找不到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"未被捕获?

+1

你为什么使用'assert'?整个断言的观点是,它们可以在运行时启用或禁用,而不会改变结果([ref](http://docs.oracle.com/javase/7/docs/technotes/guides/language/assert.html ))。对于正常的控制流程,它们不是**。来想一想,你怎么知道它捕获了完整的输入字符串?如果'assert m.matches();'行没有被执行,'m.group()'应该像m.group(“value”)那样抛出一个IllegalStateException异常。 – 2014-10-30 07:07:40

+0

你说得对。我不明白当我写这篇文章时''assert'是如何工作的。我现在已经完全取代了它。 – navari 2014-10-30 07:51:43

+0

@Alan我现在的理解是,我应该使用if语句并在else块中抛出异常。它是否正确? – navari 2014-10-30 07:57:59

回答

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 ... 
} 
+0

有没有理由为什么m.matches()不够?我觉得m.matches()隐式调用find() – navari 2014-10-30 03:58:19

+0

'matches()'方法将正则表达式与传递给'matcher()'的整个字符串进行匹配。如果正则表达式匹配整个字符串,则'matches()'返回true。如果不是,则返回false。 – hwnd 2014-10-30 04:03:27

+0

但是,如果在'matches()'中找到匹配项,那么它是否也应该找到它中的组?如果字符串是“”Data:5 Total XQWEQWE“'?在这种情况下,我想通知没有匹配完整的字符串?我是否需要额外调用'matches()'来完成该操作? – navari 2014-10-30 04:15:11