Почему Matcher.group () не может обнаружить повторение? - PullRequest
2 голосов
/ 09 декабря 2011

когда я использую этот код для извлечения элементов, регулярное выражение не обнаруживает повторения, спасибо за любую помощь.

public static void main(String[] args) {
    String input = "item1  , item2  , item3 , item4 ";
    String regex = "\\s*([a-z]\\w+)(\\s*,\\s*([a-z]\\w+))*\\s*";
    System.out.println(input.matches(regex));
    Pattern pat = compile(regex);
    Matcher m = pat.matcher(input);
    m.find();
    for (int i = 0; i < m.groupCount(); i++) {
        System.out.println(m.group(i));
    }
}

Вывод:

true
item1  , item2  , item3 , item4 
item1
 , item4

яожидая увидеть:

true
item1  , item2  , item3 , item4 
item1
,item2    
,item3
,item4 

Ответы [ 4 ]

3 голосов
/ 09 декабря 2011

А почему бы вам не использовать split?

String[] items = input.split(", ");
for (String s : items) {
    System.out.println(s);
}

Если я правильно понимаю, вы хотите извлечь элементы из входной строки. Поскольку они разделены пробелами, запятыми или их комбинацией, вы можете просто разделить их, используя регулярное выражение "," в качестве параметра для метода split, и элементы будут сохранены в возвращаемом String[].

2 голосов
/ 09 декабря 2011

Повторяющаяся часть регулярного выражения не входит в захваченную группу. Попробуйте это:

String regex = "\\s*([a-z]\\w+)((?:\\s*,\\s*([a-z]\\w+))*)\\s*";
1 голос
/ 09 декабря 2011

Я не появляюсь, Java может делать переменное количество переменных захвата.Он правильно использует группировку для совпадения в целом, но перезаписывает все повторы буфера захвата.Это типично для двигателей в стиле PCRE.Dot Net может сделать это очень хорошо.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Main
{
public static void main(String[] args) {
    String input = "item1  , item2  , item3 , item4 ";
    String regex = "^\\s*([a-z]\\w+)\\s*,\\s*([a-z]\\w+)\\s*,\\s*([a-z]\\w+)\\s*,\\s*([a-z]\\w+)\\s*$";
    Pattern pat = Pattern.compile(regex);
    Matcher m = pat.matcher(input);
    m.find();
    for (int i = 1; i <= m.groupCount(); i++) {
        System.out.println(m.group(i));
    }
    System.out.println("----------");
    regex = "^\\s*([a-z]\\w+)(?:\\s*,\\s*([a-z]\\w+))*\\s*$";
    pat = Pattern.compile(regex);
    m = pat.matcher(input);
    m.find();
    for (int i = 1; i <= m.groupCount(); i++) {
        System.out.println(m.group(i));
    }
}
}


Output:

item1
item2
item3
item4
----------
item1
item4
0 голосов
/ 09 декабря 2011

Matcher.find метод возвращает boolean, указывающее, есть ли совпадение.У вас должен быть внешний цикл, проверяющий его:

while (m.find()) {
  for (int i = 0; i < m.groupCount(); i++) {
    System.out.println(m.group(i));
  }
} 

. Он может корректно обрабатывать как случаи с нулевым совпадением, так и случаи с множественными совпадениями.*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...