2017-06-03 176 views
8

我下面的代码,并在其中我试图打印所有使用Matcher.group()字符串中的匹配。为什么Matcher.group抛出IndexOutOfBoundsException异常

public static void main(String[] args) { 
     String s = "foo\r\nbar\r\nfoo" 
       + "foo, bar\r\nak = " 
       + "foo, bar\r\nak = " 
       + "bar, bar\r\nak = " 
       + "blr05\r\nsdfsdkfhsklfh"; 
     //System.out.println(s); 
     Matcher matcher = Pattern.compile("^ak\\s*=\\s*(\\w+)", Pattern.MULTILINE) 
       .matcher(s); 
     matcher.find(); 
     // This one works 
     System.out.println("first match " + matcher.group(1)); 
     // Below 2 lines throws IndexOutOfBoundsException 
     System.out.println("second match " + matcher.group(2)); 
     System.out.println("third match " + matcher.group(3)); 

    } 

上面的代码抛出线程 “main” java.lang.IndexOutOfBoundsException 异常:无组2异常。

所以我的问题是Matcher.group()如何工作和正如你可以看到我会有3个匹配的字符串,我怎么能打印所有使用group()

+0

你可能想要设置一个断点来检查'matcher'是什么,'group'和'find'如何相互作用等等。 – luk2302

+0

@ luk2302,我确实使用过调试器,但并不知道'group'和'find '互动, –

回答

7

很显然,您只有一个组:

^ak\\s*=\\s*(\\w+) 
//   ^----^----------this is the only group 

相反,你必须使用例如环:

while(matcher.find()){ 
    System.out.println("match " + matcher.group()); 
} 

输出

match = foo 
match = bar 
match = blr05 

了解groups

捕获组

括号组之间的正则表达式。他们将由正则表达式匹配的文本捕获到编号为 的组中,该组可以通过编号的反向引用重新使用。它们允许你 将正则表达式运算符应用于整个分组正则表达式。

+0

为什么只有1组?它如何创建,我不能创建多个组,以便不迭代我可以将它们全部打印出来。 –

+0

该组是在圆括号之间定义的,所以在你的模式中你只有'(\\ w +)',所以它的意思是你只有一个组@AmitK得到它? –

+1

明白了,谢谢 –

2

您似乎被捕获组和您的字符串中找到的匹配数与给定模式混淆。在您使用的模式,你只有一个捕获组

^ak\\s*=\\s*(\\w+) 

A捕获组是在图案使用括号标记。

如果你想找回你对输入字符串模式的每一个比赛,那么你应该使用一个while循环:

while (matcher.find()) { 
    System.out.println("entire pattern: " + matcher.group(0)); 
    System.out.println("first capture group: " + matcher.group(1)); 
} 

Matcher#find()每次调用将应用模式对输入字符串,从开始结束,并会提供任何比赛。

+0

非常感谢您的好解释+1。 –

相关问题