Matcher возвращает совпадения по шаблону регулярных выражений, но split () не может найти совпадение по тому же регулярному выражению? - PullRequest
1 голос
/ 31 января 2010

Я не вижу причины, по которой Matcher возвращает совпадение в шаблон, но split возвращает массив нулевой длины в том же шаблоне регулярных выражений. Он должен что-то возвращать - в этом примере я ищу возвращение двух отдельных строк, содержащих «param / value».

public class MyClass {

    protected Pattern regEx = "(([a-z])+/{1}([a-z0-9])+/?)*";

    public void someMethod() {
        String qs = "param/value/param/value";
        Matcher matcherParamsRegEx = this.regEx.matcher(qs);
        if (matcherParamsRegEx.matches()) { // This finds a match.
            String[] parameterValues = qs.split(this.regEx.pattern()); // No matches... zero length array.
        }
    }
}

Ответы [ 3 ]

4 голосов
/ 31 января 2010

Шаблон может соответствовать всей строке. split() не возвращает совпадение, только то, что находится между ними. Поскольку шаблон соответствует всей строке, остается только пустая строка для возврата. Я думаю, что у вас может быть неправильное представление о том, что делает split().

Например:

String qs = "param/value/param/value";
String pieces = qs.split("/"); 

вернет массив из 4 элементов: параметр, значение, параметр, значение.

Обратите внимание, что то, что вы ищете ("/"), не возвращается.

Ваше регулярное выражение несколько сложнее. Во-первых, вы используете {1}, что не нужно. Во-вторых, когда вы делаете ([a-z])+, вы захватываете ровно одну последнюю (последнюю найденную. Сравните это с ([a-z]+), которая захватит весь матч. Кроме того, вам даже не нужно захватывать для этого. быть упрощенным до:

protected Pattern regEx = Pattern.compile("[a-z]+/([a-z0-9]+/?)*");

Технически это:

protected Pattern regEx = "(([a-z])+/{1}([a-z0-9])+/?)*";

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

2 голосов
/ 31 января 2010

Регулярное выражение соответствует - если это не так, вы получите массив из одного элемента, причем этот элемент представляет собой всю исходную строку. Вы просто неправильно поняли, как работает split(). При первой попытке сопоставления он находит «param / value /» и сохраняет все предшествующее этому совпадению в качестве первого токена: пустую строку. Вторая попытка находит «param / value» и сохраняет все, что лежит между ним и первым соответствием, как следующий токен: еще одну пустую строку. Третья попытка сопоставления не удалась, поэтому все, что было между вторым совпадением и концом строки, становится последним токеном: еще одна пустая строка.

Сохраняя все токены, split() перебирает их в обратном порядке, проверяя наличие пустых токенов. Третий токен действительно пуст, поэтому он удаляет этот. Второй также пуст, поэтому он удаляет этот. Вы видите, куда это идет? Вы можете заставить split() сохранить конечные пустые совпадения, передав в качестве второго аргумента отрицательное целое число, но это, очевидно, не приносит вам никакой пользы. Вам нужно переосмыслить свою проблему (какой бы она ни была) с точки зрения того, как на самом деле работает пакет regex.

2 голосов
/ 31 января 2010

Проблема в том, что split разбивает вокруг совпадений вашего регулярного выражения. У вас есть два последовательных матча, между которыми ничего нет, поэтому для возврата split ничего не остается.

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

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

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