2017-06-03 174 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。 –

相關問題