Какое состояние сохраняется в 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() это работает как ожидалось.

Другие вопросы по тегам