Какое состояние сохраняется в Java matcher.find() после неудачного сопоставления с квантификаторами?
В следующем я ожидаю, что второй find () будет успешным, но это не так. Зачем?
Matcher matcher =
Pattern.compile("\\s*asdf").matcher("apple banana cookie");
// returns false as expected
matcher.find();
// resets groups (that weren't being explicitly being used anyway), but not state.
matcher.usePattern(Pattern.compile("\\s*banana"));
// returns false, expected true.
System.out.println(matcher.find());
Если квантификатор удаляется из первого регулярного выражения (становится просто "asdf"), второе совпадение завершается успешно. Просмотр объекта Matcher показывает, что некоторая групповая информация сохраняется после первого неудачного поиска (), хотя я бы этого не ожидал. Find() должен начинаться либо с начала (если нет предыдущего совпадения), либо с индекса последнего успешного совпадения. Предполагается, что UsePattern() сохраняет позицию Matcher во входных данных и отбрасывает информацию о группе (что, опять же, я не использовал явно).
Я что-то упускаю, но не знаю что. Я подозреваю, что я должен реализовать это с помощью LookingAt() и обновления региона (например, в этом примере), но я не знаю, почему этот подход не работает.
2 ответа
Похоже, документация немного вводит в заблуждение (или на самом деле, она просто не указывает), каково поведение при вызове find()
после неудачи.
Я предполагаю, что ожидаемое использование find()
вызывается повторно до сбоя, но никогда после сбоя без сброса.
Просмотр исходного кода подтверждает, что Matcher
имеет индекс (поле last
) из которого он начинает поиск при выполнении следующего 'find()', и когда find()
не удается, этот индекс продвигается до конца и не сбрасывается.
reset()
сбрасывает этот индекс, usePattern()
не делает.
Ваш первый регулярное выражение потребляет всю строку (\\\\s*)
, Когда запускается второе регулярное выражение, нечего сопоставлять.
Если вы позвоните matcher.reset()
это работает как ожидалось.