6.5. Основы Kotlin. Регулярные выражения RegExp

Предыдущий раздел

Регулярные выражения (RegExp) — специальный язык для описания множества строк. Они помогают решать задачу поиска какого-либо текста (из описанного множества) в другом тексте, описывают интересующий нас текст и работают достаточно эффективно для быстрого решения задачи поиска.

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

Примеры регулярных выражений (см. слайды):

  • KotlinAsFirst
  • [A-Z0-9._%-]@[A-Z0-9.-]+\.[A-Z]{2,}
  • ˆ4[0-9]{12}(?:[0-9]{3})?$
  • [-]?[0-9]*\.?[0-9]
  • <()([ˆ<])(?:>(.)<\/\1>|\s+\/>)

Поиск регулярного выражения осуществляется с помощью автомата с состояниями, или конечного автомата. В данном случае под этим понимается алгоритм, имеющий некоторое количество устойчивых состояний. Для каждого состояния определяются действия, которые алгоритм выполняет в этом состоянии, а также условия, по которым алгоритм переходит в другие состояния.

Возможности языка регулярных выражений

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

  • KotlinAsFirst
  • Трансмогрификация
  • Мама мыла раму
  • 42

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

  • [0123456789] — любая цифра
  • [aeiouy] — любая буква из перечисленных
  • [~!@#$%^&*+-] — любой символ из перечисленных

Отрицание класса символов ищет любой символ НЕ из заданного множества:

  • [^0123456789] — всё, что угодно, кроме цифры
  • [^a-z] — всё, что угодно, кроме строчной латинской буквы
  • [^-az] — всё, что угодно, кроме -az

Классы и их отрицания, как видим, используют специальные символы […​] для обозначения класса, специальный символ - для обозначения интервала символов и последовательность [^…​] для обозначения отрицания.

Якоря позволяют найти начало или конец всей строки:

  • ^fun — fun в начале строки
  • \.$ — точка в конце строки
  • ^Kotlin is great as the first language!$ — ВСЯ строка с заданной фразой (и более ничем)

Здесь ^ используется для обозначения начала строки, а $ для обозначения конца. Следует иметь в виду, что якоря никак не учитывают переводы строк — имеется в виду начало или конец всего текста, а не одной строки в тексте.

\. использует экранирование для обозначения символа ., поскольку в регулярных выражениях точка является специальным символом (и обозначает любой символ). Таким образом, \ в регулярных выражениях экранирует последующий символ, делая его из специального символа обыкновенным. Для обозначения символа \ применяется пара \\. Аналогично, \^ обозначает символ-шапку, \$ — символ доллара, \[ — открывающую квадратную скобку,\] — закрывающую квадратную скобку.

Особые символы ищут символы по специальным правилам:

  • ` …​.. ` — любая последовательность из пяти символов, начинающаяся и заканчивающаяся пробелов
  • \t — табуляция, \n — новая строка, \r — возврат каретки (два последних символа унаследованы компьютерами от эпохи пишущих машинок, когда для начала печати с новой строки необходимо было выполнить два действия — возврат каретки в начало строки и перевод каретки на новую строку)
  • \s — произвольный вид пробела (пробел, табуляция, новая строка, возврат каретки)
  • \d — произвольная цифра, аналог [0-9]
  • \w — произвольная “символ в слове”, обычно аналог [a-zA-z0-9], то есть, латинская буква или цифра
  • \S — НЕ пробел, \D — НЕ цифра, \W — НЕ “символ в слове”

Шаблон выбора | ищет одну строку из нескольких, например:

  • Марат|Михаил — Марат или Михаил
  • ^\[|\]$ — открывающая квадратная скобка в начале строки или закрывающая в конце
  • for.(val|var). — цикл for с последующим val или var

Шаблоны количества ищут определённое число совпадений:

  • .* — любое количество (в том числе ноль) любых символов
  • (Марат)+ — строка Марат один или более раз (но не ноль)
  • (Михаил)? — строка Михаил ноль или один раз
  • ([0-9]{4}) — последовательность из ровно четырёх любых цифр
  • \w{8,16} — последовательность из 8-16 “символов в слове”

Круглые скобки () задают так называемые группы поиска, объединяя несколько символов вместе.

  • (Kotlin)+AsFirst — KotlinAsFirst, KotlinKotlinAsFirst, KotlinKotlinKotlinAsFirst, …​
  • (?:\$\$)+ — `, ``, `, …​
  • (\w+)\s\1 — слово, за которым следует пробел и то же самое слово.
  • fun\s+(/w+)\s*\{.\1.\} — fun с последующими пробелами, произвольным словом в круглых скобках, пробелами и тем же словом в фигурных скобках

Здесь \1 (\2\3, …​) ищет уже описанную группу поиска по её номеру внутри регулярного выражения (в данном случае — первую группу). Комбинация (?:…​) задаёт группу поиска без номера. В целом, (?…​) задаёт группы особого поиска:

  • Марат(?=\sАхин) — Марат, за которым следует пробел и Ахин
  • (?⇐Михаил\s)Глухих — Глухих, перед которым стоит Михаил с пробелом
  • \d+(?![$\d]) — число, после которого НЕ стоит знак доллара
  • (?<!root\s)beer — beer, перед которым НЕ стоит root с пробелом
Додати коментар