Регулярные выражения (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]
— всё, что угодно, кроме-
,a
,z
Классы и их отрицания, как видим, используют специальные символы […]
для обозначения класса, специальный символ -
для обозначения интервала символов и последовательность [^…]
для обозначения отрицания.
Якоря позволяют найти начало или конец всей строки:
^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 с пробелом