2016-03-03 3 views
0

Я пытаюсь изучить регулярное выражение Java. Я хочу совместить несколько групп захвата (т. Е. j(a(va))) с другой строкой (то есть this is java. this is ava, this is va). Я ожидал, что выход будет:Как сопоставить несколько групп захвата, но результаты не ожидаются

I found the text "java" starting at index 8 and ending at index 12. 
I found the text "ava" starting at index 21 and ending at index 24.  
I found the text "va" starting at index 34 and ending at index 36. 
Number of group: 2 

Однако IDE вместо только выход:

I found the text "java" starting at index 8 and ending at index 12. 
Number of group: 2 

Почему это так? Есть что-то, чего я не хватает?

Оригинальный код:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
System.out.println("\nEnter your regex:"); 

     Pattern pattern 
       = Pattern.compile(br.readLine()); 

     System.out.println("\nEnter input string to search:"); 
     Matcher matcher 
       = pattern.matcher(br.readLine()); 

     boolean found = false; 
     while (matcher.find()) { 
      System.out.format("I found the text" 
        + " \"%s\" starting at " 
        + "index %d and ending at index %d.%n", 
        matcher.group(), 
        matcher.start(), 
        matcher.end()); 
      found = true; 
      System.out.println("Number of group: " + matcher.groupCount()); 
     } 
     if (!found) { 
      System.out.println("No match found."); 
     } 

После запуска кода выше, я поступил следующий вход:

Enter your regex: 
j(a(va)) 

Enter input string to search: 
this is java. this is ava, this is va 

И IDE выходы:

I found the text "java" starting at index 8 and ending at index 12. 
Number of group: 2 
+1

попробуйте использовать https://regex101.com/ –

+1

Я думаю, вы поняли, что делать захватывая группы. Они не делают другие части регулярного выражения необязательными, поэтому ваше регулярное выражение совпадает только со всей строкой 'java'. – Barmar

+1

Пожалуйста, не публикуйте вопросы, прочитанные из 'System.in', и делайте что-то с результатом, так как это означает, что вы можете легко отладить код, чтобы идентифицировать ошибку при чтении из' System.in' или b) hardcode. строки. В обоих случаях это означает, что код не является минимальным примером и/или источник ошибки можно легко сузить. Кроме того, это означает, что больше работы по воспроизведению проблемы. – fabian

ответ

1

Ваше регулярное выражение соответствует только вся строка java, она не соответствует ava или va. Когда он будет соответствовать java, он установит группу захвата 1 в ava и возьмет группу 2 до va, но она не будет соответствовать этим строкам самостоятельно. Регулярное выражение, которое будет производить результат, который вы хотите это:

j?(a?(va)) 

? делает предыдущий пункт необязательным, поэтому он будет соответствовать более поздние элементы без префиксов.

DEMO

+0

Большое вам спасибо за помощь! Действительно ценю это!! – Thor

1

Вам необходимо регулярное выражение (j?(a?(va)))

Pattern p = Pattern.compile("(j?(a?(va)))"); 
Matcher m = p.matcher("this is java. this is ava, this is va"); 

while(m.find()) 
{ 
    String group = m.group(); 
    int start = m.start(); 
    int end = m.end(); 
    System.out.format("I found the text" 
        + " \"%s\" starting at " 
       + "index %d and ending at index %d.%n", 
        group, 
        start, 
        end); 



} 

Вы можете увидеть демо here

Смежные вопросы