Регулярные выражения в Kotlin: простые примеры для работы

Каждый разработчик рано или поздно сталкивается с задачей: проверить, правильно ли введён email, вытащить из строки все цифры или разбить текст по заковыристому шаблону. Писать для этого длинные цепочки условий — плохой путь. Kotlin регулярные выражения дают короткое и мощное решение. В этом уроке я объясню, что такое Regex, как создавать шаблоны и применять их в реальных сценариях, даже если вы никогда не слышали о регулярках раньше.


Что такое регулярное выражение

Регулярное выражение — это строка-шаблон, которая описывает, какие последовательности символов мы хотим найти в тексте. Например, шаблон \d+ означает «одна или несколько цифр подряд». Передав его в Kotlin-класс Regex, вы можете найти все числа в предложении или проверить, соответствует ли строка формату телефона.

Главный плюс — универсальность. Один и тот же шаблон работает похожим образом в Kotlin, Java, Python, JavaScript и даже в базах данных. Поэтому разобравшись с регулярками однажды, вы сможете использовать их в любых проектах.


Как создать Regex в Kotlin

Самый частый способ — вызвать метод toRegex() на обычной строке. Kotlin также позволяет создать объект через конструктор Regex() и при необходимости задать флаги, которые меняют поведение шаблона.

val pattern = "\\d+".toRegex()           // через строку
val pattern2 = Regex("\\d+")             // через конструктор
val pattern3 = Regex("\\d+", RegexOption.IGNORE_CASE) // с флагом

Обратите внимание: в строке Kotlin обратный слеш нужно экранировать, поэтому вместо одинарного \d пишем \\d. Если вы используете raw-строку (тройные кавычки), экранирование не требуется: """\d+""".toRegex().

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

val literal = Regex.fromLiteral("hello.world") // найдёт именно hello.world, а не h-любой символ

Самые нужные методы Regex

Таблица ниже содержит основные методы класса Regex. Это ваш шпаргалка для повседневной работы с текстом.

Метод Что делает Пример использования
containsMatchIn(input) Проверяет, есть ли в строке хотя бы одно совпадение "abc".containsMatchIn("123abc456") // true
matches(input) Проверяет, соответствует ли вся строка шаблону целиком "\\d+".matches("123") // true
find(input) Находит первое совпадение, возвращает MatchResult? "\\d+".find("abc123def")?.value // "123"
findAll(input) Находит все совпадения, возвращает Sequence<MatchResult> "\\d+".findAll("a1b22c333").map { it.value }.toList() // ["1","22","333"]
replace(input, replacement) Заменяет все совпадения на строку-заменитель "\\s+".replace("a b c", " ") // "a b c"
split(input) Разрезает строку по местам совпадений, возвращает список ",".toRegex().split("a,b,c") // ["a","b","c"]

Поиск и проверка совпадений

Начнём с простого: проверка строки на соответствие формату. Допустим, нужно узнать, является ли введённый текст четырёхзначным числом. Используем якоря ^ (начало строки) и $ (конец строки), чтобы совпадение шло по всей длине, а не где-то внутри.

val pinPattern = "^\\d{4}$".toRegex()
println(pinPattern.matches("1234"))  // true
println(pinPattern.matches("12345")) // false

Если нужно просто узнать, есть ли слово в тексте, подойдёт containsMatchIn. Это самый быстрый способ проверки.

val word = "kotlin".toRegex(RegexOption.IGNORE_CASE)
println(word.containsMatchIn("Я изучаю Kotlin")) // true

Извлечение данных из текста

Самая частая задача — вытащить из строки все цифры, email-адреса или номера телефонов. Комбинация findAll и лямбды делает это в одну цепочку. Никаких циклов не требуется.

val text = "Контакты: +7(999)123-45-67, +7(495)000-11-22"
val phoneRegex = "\\+7\\(\\d{3}\\)\\d{3}-\\d{2}-\\d{2}".toRegex()
val phones = phoneRegex.findAll(text).map { it.value }.toList()
// ["+7(999)123-45-67", "+7(495)000-11-22"]

Если достаточно только первого совпадения, используйте find. Он возвращает объект MatchResult, у которого есть удобные свойства: value (найденная подстрока), range (диапазон индексов), groupValues (захваченные группы).

val match = phoneRegex.find(text)
println(match?.value)   // +7(999)123-45-67
println(match?.range)   // 10..25

Группы: захват частей совпадения

Группы — это самая мощная фича регулярных выражений. Они позволяют не просто найти шаблон, но и разобрать его на смысловые куски. Всё, что заключено в круглые скобки в шаблоне, становится группой. Доступ к содержимому групп идёт через groupValues, где нулевой элемент — полное совпадение, а следующие — содержимое скобок по порядку.

val datePattern = "(\\d{2})/(\\d{2})/(\\d{4})".toRegex()
val dateText = "Сегодня 09/05/2026"
val dateMatch = datePattern.find(dateText)
if (dateMatch != null) {
    val day = dateMatch.groupValues[1]   // "09"
    val month = dateMatch.groupValues[2] // "05"
    val year = dateMatch.groupValues[3]  // "2026"
    println("День: $day, Месяц: $month, Год: $year")
}

Именованные группы тоже поддерживаются: используйте синтаксис (?<name>...), а для доступа — свойство groups["name"]?.value. Это удобно для сложных шаблонов, где сложно запомнить порядок скобок.


Замена текста по шаблону

replace и replaceFirst работают как «найти и заменить» в текстовом редакторе, только автоматически. В строке-заменителе можно ссылаться на группы через $1, $2. Например, поменяем дату с формата ДД/ММ/ГГГГ на ГГГГ-ММ-ДД.

val dateText = "Событие: 09/05/2026"
val newDate = datePattern.replace(dateText) { match ->
    "${match.groupValues[3]}-${match.groupValues[2]}-${match.groupValues[1]}"
}
println(newDate) // "Событие: 2026-05-09"

Для замены всех лишних пробелов на один достаточно шаблона \s+:

val spaced = "Это   слишком   много   пробелов"
val clean = "\\s+".toRegex().replace(spaced, " ")
println(clean) // "Это слишком много пробелов"

Разделение строки

Метод split принимает Regex и режет строку в каждом месте совпадения. В отличие от обычного split с символом, здесь можно задать сложный разделитель: несколько запятых подряд, пробелы или любой символ.

val csv = "apple;banana,,orange"
val items = "[;,]".toRegex().split(csv).filter { it.isNotEmpty() }
println(items) // ["apple", "banana", "orange"]

Если разделителей несколько видов, шаблон "[,;]".toRegex() обработает их все за один проход. Не забывайте фильтровать пустые строки, которые могут появиться при повторяющихся разделителях.


Коротко о главном

Kotlin регулярные выражения — это компактный и гибкий инструмент для обработки текста. Вы научились создавать Regex через toRegex(), проверять строки с matches и containsMatchIn, извлекать данные через find и findAll, а также заменять и разделять текст. Начните с простых шаблонов: валидация email, поиск чисел, уборка лишних пробелов — и постепенно двигайтесь к более сложным выражениям. Запомните главное: регулярка не страшна, если разбирать её по кусочкам.