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

Регулярные выражения в Котлине

Для описания регулярных выражений в Котлине используется тип 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.

Полезные ссылки

Следующий раздел

Додати коментар