Регулярные выражения в Java

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

Регулярные выражения являются объектами классов Pattern и Matcher. Эти классы являются частью пакета java.util.regex, который предоставляет основной функционал для работы с регулярными выражениями. Они же предоставляют набор статических методов для поиска совпадений в строке. Совпадения возвращаются в виде различных типов данных, в зависимости от используемого метода: Int, String, Boolean. Сам шаблон для поиска является объектом типа Pattern или Matcher и сохраняется в переменную одного из данных типов.

Синтаксис регулярных выражений

Шаблон регулярного выражения может быть представлен в 2-х видов:

  1. Сплошная строка. Шаблон в виде строки «Google» совпадает со строкой «Google».
  2. Строка с ограничителями. В качестве ограничителей используются специальные символы: квантификаторы, диапазоны, символы исключения (метасимволы). К примеру, в строке «Google» нужно найти часть слова после первого символа «o», шаблон будет выглядеть следующим образом: «o(\\w*)». Результатом станет «oogle». Здесь «\W*» метасимвол, который говорит о том, что после «о» может находиться сколько угодно символов. Метасимволы и другие специальные конструкции отделяются скобками.

Часто для указания шаблона используется не один специальный символ, а серия: «(^[fa])(\\D)»- найдет все совпадения, в которых отсутствует «fa» и в которых отсутствуют цифры.

Как работать с регулярными выражениями

Как уже упоминалось ранее, регулярные выражения являются объектами классов Pattern и Matcher. Поэтому, чтобы иметь возможность создавать соответствующие объекты, необходимо импортировать пакет java.util.regex.Pattern. Однако одного паттерна недостаточно и требуется импорт обеих классов. Что работать сразу с двумя, требуется ниже добавить java.util.regex.Matcher. Без импорта нельзя обращаться к несуществующим классам. Ведь методы класса Pattern создают и сохраняют шаблон, а методы класса Matcher находят и сохраняют совпадения.

Пример с шаблоном в виде простой строки:

importSystem.out; \\Импортирован класс out, чтобы не писать полную конструкцию для вывода строк в консоль.

public class FindMatch {

public static void Main(String[] args) {
Stringstr = «Train»; \\ Исходная строка в которой будет вестись поиск
Patternp = Pattern.compile(str);\\ Инициализация объекта шаблона
Matcherm = p.matcher(str); \\ Сохранение результата сравнения
println(m.matches()) \\ Вывод результат выполнения метода, который отобразит true
}
}

Пояснение к примеру:

  1. До объявления главного класса были импортированы классы Pattern и Matches.
  2. Инициализация строки str значением «Train».
  3. Сохранение в объект pattern класса Pattern результата статического метода этого же класса compile c параметром, он же шаблон «Train».
  4. Сохранение в объект matcher класса Matcher результата статического метода объекта pattern. Метод matcher принимает в качестве аргумента переменную str и сравнивает ее значение со значением объекта p. Если шаблон и значение совпадают, то возвращается объект класса Matcher c результатом сравнения.
  5. Результат выводится на экран с помощью метода matches() и равен true.

Пример с метасимволом:

ImportSystem.out;
public static void Main(String[] args) {
String s = «First Place! Second PlacePlace! Place№ 6.»;
Pattern p = Pattern.compile(«Place(\\w*)»);
Matcher m = pattern.matcher(s);
while(m.find()) \\ Пока совпадения находятся, итерации цикла будут выполняться
print(m.group()); // Первый вывод Place, второйPlacePlace, третий Place
}

Пояснение к примеру:

  1. Сохранение в строковую переменную значения «FirstPlace! SecondPlacePlace! Place№ 6.».
  2. Сохранение шаблона «Java(\\w*)» в переменную pattern, который возвращает статический метод compile(). Здесь в строке будут искаться все значения «Java» с буквенными символами, которые идут после них, пунктуация, числа и пробелы будут игнорироваться за счет метасимвола \w*, находящегося в шаблоне.
  3. Результат совпадения сохраняется в объект m класса Match.
  4. Цикл While будет выполняться до тех пор, пока метод find() будет находить совпадения в строке.
  5. При каждом срабатывании find(), будет выводиться на экран результат метода group() в виде строки совпадения. Данный метод срабатывает только при положительном результате, возвращаемым методом find().
  6. Результатом вывода станет три совпадения, а на экране отобразится строка «PlacePlacePlacePlace№ 6».

Не обязательно всегда сохранять строку для сравнения с шаблоном. Метод mather() в качестве аргумента может принимать не переменную, а строку — matcher(«Place»).

Группы шаблонов

Можно установить, как один шаблон для поиска, так и их группу, сохранив ее в один объект класса Pattern. Группа шаблонов помещается в круговые скобки и выглядит следующим образом: ((pattern1) (pattern2)).

Здесь в первой скобке организовывается первый шаблон в виде специального символа, во второй скобке второй другой шаблон. Вне скобок можно помещать строку или специальный символ. В итоге, будет искаться соответствие по первому и второму шаблону. Если хоть один из них не совпадает, то метод find() вернет false.

Вывод результата на экран или проверка строки на соответствие осуществляется через цикл, или проверяется на соответствие с помощью метода group(0). В качестве аргумента данного метода используется числовой индекс скобок — первая скобка равна 0, вторая 1 и так далее.

Методы класса Pattern

  • Pattern.pattern() — статический метод, который возвращает строковое представление шаблона регулярного выражения.
  • Pattern.compile(regsp, param) — статический метод, который сохраняет шаблон в объект класса Pattern или Matcher. Первый параметр обязательный и является шаблоном. Второй необязательный может быть трех видов: CASE_INSENSITIVE — игнорирует регистр символов; LITERAL — специальные символы строки, такие как пробелы или пунктуация, становятся обычными; UNICODE_CASE — игнорирует регистр символов формата unicode.
  • Pattern.matches(regexp, charseq) — возвращает true или false если шаблон regexp соответствует строке или символу charseq.
  • Pattern.split(charseq, limit) — делит текст строки на массив символов типа String, переданный в параметр charseq. Параметр лимит задает количество совпадений, которое должно быть найдено в первом параметре, где: limit> 0 — поиск совпадений по числу; limit< 0 — поиск всех совпадений до конца строки; limit = 0 — ищет все совпадения кроме пустых символов в конце строки.
  • patt.matcher(string) — проводит поиск в строке параметра string и возвращает результат как объект класса Matcher.

Методы класса Matcher

  • Pattern.compile(«шаблон») — создается шаблон и сохраняется в объект Mather.
  • pat.matches() — если вся строка совпадает с шаблоном, то возвращает true, в противном случае false.
  • pat.find() — возвращает true, если в строке была найдена подстрока, соответствующая шаблону. Если совпадений несколько, то метод после обнаружения первого совпадения, после повторного вызова находит следующее совпадение.
  • pat.group() — метод возвращает совпадение в строковом формате после положительного результата вызова метода find(). При отсутствии совпадения, метод создает исключение IllegalStateException.
  • pat.start() — также в зависимости от порядка найденного совпадения методом find(), метод start() возвращает индекс совпадения, начиная с начала строки.
  • pat.end() — метод аналогичен предыдущему, только возвращает индекс следующего совпадения, после найденного текущего.
  • pat.replaceAll(string) — метод осуществляет замену всех текущих совпадений на строку в параметре string и возвращает измененную строку, сохраняя ее в переменную класса String.

Список всех специальных символов

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

Метасимволы

Метасимволы указывают место поиска подстроки и формат соответствия:

  1. ^ — ищет совпадения в начале строки и игнорирует регистр букв.
  2. $ — ищет совпадения в конце строки, игнорируя регистр.
  3. . — находит любой отдельный символ.
  4. | — отделитель шаблонов, находящий соответствие любого из них. К примеру, dog|cat|bird — находит совпадение с одной или несколькими строками шаблона.
  5. \A — поиск совпадений в начале строки, false если находит в конце.
  6. \z — поиск в конце строки.
  7. \w — ищет совпадение только по буквенным символам.
  8. \W — ищет совпадения только не по буквенным символам.
  9. \s — находит с пробелами.
  10. \S — находит без пробелов.
  11. \d — находит с цифрами.
  12. \D — исключает цифры.
  13. \G — находит точку конца последнего совпадения.
  14. \b — возвращает строку в скобках.
  15. \n — совпадает переводу строки.

Квантификаторы

Квантификаторы создают шаблон для поиска отдельного символа, очереди и ограничивают их количество, а также меняют порядок поиска:

  1. r* — здесь «r» выступает в роли шаблона, а «*» говорит о том, что искать нужно все совпадения до конца строки.
  2. r+ — знак «+» говорит о том, что совпадений должно быть не менее одного.
  3. r? — соответствует одному совпадению символов или одного символа «r».
  4. r{x} — соответствует символам «r», которые пишутся слитно x-раз.
  5. r{x,y} — совпадает от x до y.
  6. r{x,} — ищет совпадения, где символ «r» пишется слитно не менее x-раз.

Скобки

Скобочные конструкции предоставляют дополнительные опции для поиска:

  1. […] — соответствует любому отдельному символу, находящемуся в скобках.
  2. [^…] — исключает поиск символа, находящегося в скобках.

Примеры использования специальных символов

Допустим есть строка «Hello World2020»:

  • «(([h])(\\A))» найдет «H»;
  • «(([0])(\\z))» найдет символ «0» в конце строки.
  • «[o]*» найдет «o, o».
  • «[^l]{2}» найдет «H, e, o, W, o, r, l, d, 2, 0, 2, 0».

Лучшие источники информации по регулярным выражениям Java

Существуют отдельные печатные издания, которые предоставляют общую информацию о регулярных выражениях:

  1. Лойан Гронер, Габриэль Манрикс «Регулярные выражения в JavaScript».
  2. Майкл Фицжеральд «Введение в регулярные выражения».
  3. Фридл Дж. «Регулярные выражения».
  4. Гойвертс Я., Левитан С. «Регулярные выражения. Сборник рецептов».
  5. ChildDave. «Шпаргалка по регулярным выражениям».

Рекомендуемые ресурсы:

  • W3Cschools.com — сайт предоставляет информацию по основам Java, а также регулярным выражениям для этого языка и других.
  • javarush.ru — также предоставляет уроки изучения Java и отдельно описание работы с регулярными выражениями.
  • javahelp.online — подробно на простых примерах описываются приемы использования простых и сложных шаблонов.

В целом для изучения регулярных выражений Java подойдет любой учебник, описывающий общую концепцию регулярных выражений. Остается только вникнуть в функциональность классов Pattern и Matcher, которые были разработаны исключительно для Java. Стоит отметить, что если не использовать среду разработки для написания кода, а ограничиваться лишь консолью, то пакет java.util.regex придется загружать отдельно, чтобы можно было подключить соответствующие классы.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *