Перехват перекрывающихся групп - PullRequest
4 голосов
/ 01 апреля 2011

Пожалуйста, посмотрите на следующий код:

public static void main(String[] args) {
    String s = "a < b > c > d";
    String regex = "(\\w\\s*[<>]\\s*\\w)";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(s);
    int i = 0;
    while (m.find()) System.out.println(m.group(i++));
}

Вывод вышеуказанной программы: a < b, c > d

Но я на самом деле ожидаю a < b, b > c, c > d.

Что-то не так с моим регулярным выражением здесь?

Ответы [ 3 ]

3 голосов
/ 01 апреля 2011

Вы правы, думая, что b> c соответствует регулярному выражению, потому что это так.

Но когда вы вызываете Matcher :: find (), он возвращает следующую подстроку ввода, соответствующую регулярному выражению и не связаны с предыдущими совпадениями find ().Поскольку «b> c» начинается с «b», который был частью совпадения «a> b», возвращенного предыдущим вызовом, функция find () не будет возвращена.

2 голосов
/ 01 апреля 2011

Попробуйте это.

    String s = "a < b > c > d";
    String regex = "(?=(\\w{1}\\s{1}[<>]{1}\\s{1}\\w{1})).";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(s);
    while(m.find()) {
        System.out.println(m.group(1));
    }

Обновлено (на основе решения Грина) :

    String s = " something.js > /some/path/to/x19-v1.0.js < y < z < a > b > c > d";
    String regex = "(?=[\\s,;]+|(?<![\\w\\/\\-\\.])([\\w\\/\\-\\.]+\\s*[<>]\\s*[\\w\\/\\-\\.]+))";

    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(s);
    while (m.find()) {
        String d = m.group(1);
        if(d != null) {
            System.out.println(d);
        }
    }
1 голос
/ 04 апреля 2011

На основе решения Джона и добавления некоторых сопоставителей границ это работает наконец.

    String s = " something.js > /some/path/to/x19-v1.0.js < y < z < a > b > c > d";
    String regex = "(?=[\\s,;]+([\\w\\/\\-\\.]+\\s*[<>]\\s*[\\w\\/\\-\\.]+)[\\s,;$]*).";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(s);
    while(m.find()) {
        System.out.println(m.group(1));
    }
...