Регулярные выражения в Котлине
Для описания регулярных выражений в Котлине используется тип Regex
. Для создания регулярного выражения следует вызвать его конструктор, например Regex("KotlinAsFirst")
. Второй способ создания регулярного выражения — вызов функции toRegex()
на строке-получателе, например "KotlinAsFirst".toRegex()
.
При создании регулярных выражений вместо обычных строк в двойных кавычках рекомендуется использовать так называемые raw string literals (необработанные строки). Перед и после такого литерала должны стоять три двойных кавычки. Внутри необработанных строк не применяется экранирование, что позволяет применять специфичные для регулярных выражений символы без дополнительных ухищрений. Например: Regex("""x|+|-|\*|/|\(|\)|\d+?| +?""")
— задаёт выражение x
, или +
, или -
, или …, или число, или любое количество пробелов. Без тройных кавычек нам пришлось бы дважды записать каждый из \
.
Для анализа результата поиска применяется тип MatchResult
, который можно получить, вызвав find
на регулярном выражении-получатале: Regex("""…""").find(string, startIndex)
. find
ищет первое вхождение регулярного выражения в строку string
, начиная с индекса startIndex
(по умолчанию — 0). Если вхождений регулярного выражения не найдено, результат find
равен null.
Regex("""…""").findAll(string, startIndex)
ищет ВСЕ вхождения регулярного выражения, которые после этого можно перебрать с помощью цикла for
.
Тип MatchResult
включает в себя следующие свойства:
result.value
— подстрока исходной строки, с которой совпало регулярное выражение (совпадение)result.range
— интервал индексов символов, в котором было найдено совпадениеresult.groupValues
— список строк, 0-й элемент которого содержит всё регулярное выражение, а последующие содержат значения групп поиска из регулярного выражения (то есть размер списка равен числу групп поиска в выражении + 1)
Некоторые другие полезные методы, связанные:
Regex("""…""").replace("MyString", "Replacement") — находит в данной строке все вхождения регулярного выражения и заменяет их на `"Replacement"
"MyString".contains(Regex("""…"""))
— есть ли в данной строке хоть одно вхождение регулярного выраженияRegex("""…""").containsMatchIn("MyString")
— то же самое, но в другом порядке"MyString".matches(Regex("""…"""))
— соответствует ли данная строка данному регулярному выражениюRegex("""…""").matches("MyString")
— то же самое, но в другом порядкеRegex("""…""").split("MyString")
— деление строки на части с использованием заданного регулярного выражения как разделителя
Мини-пример:
fun timeStrToSeconds(str: String): Int { val matchResult = Regex("""(\d\d):(\d\d):(\d\d)""").find(str) if (matchResult == null) return -1 return matchResult.groupValues.drop(1).map { it.toInt() }.fold(0) { previous, next -> previous * 60 + next } }
Здесь мы разбираем исходную строку вида “12:34:56” с целью найти в ней три одинаковых группы поиска (\d\d)
. Каждая из групп поиска включает в себя две цифры. Убедившись с помощью проверки на null, что регулярное выражение успешно найдено, мы отбрасываем первый элемент groupValues
с помощью функции drop(1)
, оставляя, таким образом, в списке только значения трёх групп поиска. Далее каждая из пар цифр конвертируется в число. Результат сворачивается в число секунд, прошедших с начала дня, с помощью функции высшего порядка fold
— см. раздел 4.