2017-06-03 50 views
8

Mam poniżej kod i w którym próbuję wydrukować wszystkie dopasowania w ciągu przy użyciu Matcher.group().Dlaczego Matcher.group rzuca wyjątek 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)); 

    } 

Powyższy kod rzuca Wyjątek w wątku "głównym" java.lang.IndexOutOfBoundsException: żadna grupa 2 wyjątku.

Moje pytanie brzmi: jak działa Matcher.group()? Jak widzisz, będę miał 3 pasujące ciągi, jak mogę wydrukować je wszystkie za pomocą group().

+0

Możesz chcieć ustawić punkt przerwania i sprawdzić, co ma 'matcher', jak interakcje' group' i 'find', itp. – luk2302

+0

@ luk2302, użyłem debuggera, ale nie wiedziałem, jak' group' i 'find 'interakcja, –

Odpowiedz

7

Oczywiste jest, że masz tylko jedną grupę:

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

zamiast trzeba użyć pętli na przykład:

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

Wyjścia

match = foo 
match = bar 
match = blr05 

przeczytać o groups:

grupie Przechwytywanie

grupę nawiasach regex między nimi. Przechwytują tekst dopasowany przez regex wewnątrz nich do ponumerowanej grupy , która może być ponownie wykorzystana z numerowaną referencją wsteczną. Pozwalają one na stosowanie operatorów wyrażeń regularnych do całego zgrupowanego wyrażenia regularnego.

+0

dlaczego jest tylko 1 grupa? jak powstało i nie mogę utworzyć wielu grup tak, że bez iteracji mogę wydrukować je wszystkie. –

+0

grupa jest zdefiniowana między nawiasami, więc we wzorze masz właśnie '(\\ w +)', więc znaczy, że masz tylko jedną grupę @AmitK? –

+1

rozumiem, dziękuję –

2

Wygląda na to, że jesteś zdezorientowany przez grupy przechwytywania i liczbę dopasowań znalezionych w ciągu znaków z podanym wzorem. Na wzór został użyty, masz tylko jedną grupę przechwytywania:

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

grupa przechwytywania jest oznaczony za pomocą nawiasów we wzorcu.

Jeśli chcesz pobrać każdy mecz swojego wzoru przeciwko ciąg wejściowy, wtedy należy użyć while pętlę:

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

Każde wywołanie Matcher#find() zostanie zastosowany wzór przeciwko ciąg wejściowy, z zaczynają się kończyć i będą udostępniać wszelkie dopasowania.

+0

Bardzo dziękuję za miłe wyjaśnienie +1. –