Продолжаем изучение регулярных выражений.
В этой статье мы рассмотрим предопределенные классы символов, а также квантификацию (поиск последовательностей).
Предопределенные классы символов
API классаPattern
содержит предопределенные классы символов, предлагающие удобные сокращения часто используемых регулярных выражений.
В этой таблице конструкции в левой колонке — сокращенное представление выражений из правой колонки. Например, \d
означает цифру (0-9), \w
означает любую заглавную или прописную букву, символ подчеркивания или цифру). Используйте предопределенные классы символов, где это возможно. Это сделает ваш код проще для чтения и исправления ошибок.
Конструкции, начинающиеся с обратного слеша, называются экранированными или защищенными. В предыдущих статьях мы уже говорили об экранировании специальных символов обратным слешем или символами \Q
и \E
для использования их в качестве обычных символов. Если вы используете обратный слеш с обычными символами (литералами), то необходимо экранировать этот бэк слеш, чтобы выражение скомпилировалось.
private final String REGEX = "\\d"; // цифра
В этом примере \d
— регулярное выражение; дополнительный обратный слеш необходим для того, чтобы программа скомпилировалась. Наша тестовая программа читает регулярные выражения прямо из консоли, поэтому дополнительный слеш не нужен.
Следующий пример демонстрирует использование предопределенных символьных классов:
В первых трех примерах регулярное выражение — просто «.
» (специальный символ точка), что означает любой символ. Поэтому поиск был успешным во всех случаях. В других примерах используются предопределенные символьные классы, значения которых мы рассмотрели в таблице выше.
Квантификаторы
Квантификаторы позволяют задавать количество вхождений символа в строку. Рассмотрим подробнее тонкости работы жадных, ленивых и очень жадных квантификаторов. На первый взгляд может показаться, что квантификаторы X?, X?? и X?+ работают одинаково: «X есть один раз или нет совсем». Есть небольшие отличия в реализации этих квантификаторов, которые мы рассмотрим ниже.Совпадения нулевой длины
Начнем с жадного. Напишем три разных регулярных выражения: буква «a» со специальными символами ?, * или +. Посмотрим, что произойдет если тестировать эти регулярки на пустой строке: В примере выше, поиск был удачным в первых двух случаях, потому что выражения a? и a* допускают отсутствие символа a в строке. Также обратите внимание, что начальный и последний индексы совпадения одинаковы (0). Так как входная строка не имеет длины, программа находит ничего :) на первой же позиции. Этот случай называется совпадением нулевой длины. Такие совпадения встречаются в нескольких случаях: при пустой входной строке, в начале входной строки, после последнего символа строки или между символами строки. Совпадения нулевой длины легко обнаружить: они начинаются и заканчиваются на одной и той же позиции. Рассмотрим еще несколько примеров совпадений нулевой длины. Let’s explore zero-length matches with a few more examples. Изменим входную строку на символ «a» и наблюдаем интересный эффект: Все три квантификатора нашли символ «a», но первые два, которые допускают отсутствие символа, нашли совпадение нулевой длины на позиции 1 — после последнего символа строки. Так происходит, потому что программа воспринимает символ «a» как строку и «бежит» по ней пока совпадения не закончатся. В зависимости от используемого квантификатора, программа будет или не будет находить «ничего» в конце строки. Теперь изменим входную строку на последовательность из пяти букв «a»: Регулярное выражение a? находит совпадение для каждой буквы в строке отдельно. Выражение a* находит два совпадения: последовательность символов «a»‘ и совпадение нулевой длины на 5 позиции. И, наконец, регулярное выражение a+ находит только последовательность символов «a», не находя при этом «ничего» :) Что же будет происходить, если на вход подать строку, содержащую разные символы? Например, «ababaaaab»: Символ «b» находится на 1, 3 и 8 позициях и программа находит совпадения нулевой длины на этих позициях. Регулярное выражение a? не обращает внимания на «b», а просто ищет присутствие (или отсутствие) символа «a». Если квантификатор допускает отсутствие «a» все символы в строке отличные от «a» будут показаны как совпадение нулевой длины. Для нахождения последовательностей заданной длины, просто укажите длину в фигурных скобках: Регулярное выражение a{3} ищет последовательность из трех символов «a». В первой строке ничего не найдено, потому что в строке недостаточно символов a. Вторая содержит 3 символа, которые и находит программа. Третий тест также находит совпадение в начале строки. Все что находится за 3 символом не удовлетворяет регулярному выражению, в коде ниже — удовлетворяет и найдутся несколько совпадений: Для указания минимальной длины последовательности — используйте:
Enter your regex: a{3,}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaaaaa" starting at index 0 and ending at index 9.
В этом примере программа находит только одно совпадение, потому что строка удовлетворяет требованию минимальной длины последовательности (3) символов «a».
Наконец, задание максимальной длины последовательности:
В этом примере первое совпадение закончилось на шестом символе. Второе совпадение содержит символы после шестого, т.к. они удовлетворяют требованию минимальной длины. Если бы строка была на один символ короче, второго совпадения не было бы.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ