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

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

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

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

1. Основы работы с классом Regex

В Kotlin регулярное выражение создается с помощью класса Regex. Шаблон можно задать строкой или с помощью raw-строки (тройные кавычки """), что особенно удобно, чтобы не экранировать обратные слеши.

// Обычная строка
val pattern1 = Regex("\\d+")  // одна или более цифр

// Raw-строка (рекомендуется)
val pattern2 = Regex("""\d+""") // то же самое, но без экранирования

Класс Regex также принимает необязательные флаги, например, RegexOption.IGNORE_CASE для регистронезависимого поиска.

val caseInsensitive = Regex("""hello""", RegexOption.IGNORE_CASE)

2. Основные методы: match, find, replace

Kotlin предоставляет несколько ключевых методов для работы с регулярными выражениями. Рассмотрим самые популярные.

2.1. Метод matchEntire (полное совпадение)

Проверяет, соответствует ли вся строка шаблону. Возвращает MatchResult? или null.

val regex = Regex("""\d{3}-\d{2}-\d{4}""")
val text = "123-45-6789"
val matchResult = regex.matchEntire(text)
println(matchResult?.value) // Вывод: 123-45-6789

// Если строка не соответствует шаблону
val badText = "123-45-678"
println(regex.matchEntire(badText)) // Вывод: null

2.2. Метод find (первое совпадение)

Ищет первое вхождение шаблона в строке. Возвращает MatchResult?.

val regex = Regex("""\d+""")
val text = "Цена: 150 рублей, скидка: 30%"
val firstMatch = regex.find(text)
println(firstMatch?.value) // Вывод: 150

2.3. Метод findAll (все совпадения)

Находит все непересекающиеся вхождения шаблона. Возвращает последовательность MatchResult.

val regex = Regex("""\d+""")
val text = "Цена: 150 рублей, скидка: 30%"
val allMatches = regex.findAll(text)
allMatches.forEach { println(it.value) }
// Вывод:
// 150
// 30

2.4. Метод replace (замена)

Заменяет все вхождения шаблона на указанную строку или результат лямбды.

val regex = Regex("""\d+""")
val text = "ID: 12345, код: 67890"
val result = regex.replace(text, "***")
println(result) // Вывод: ID: ***, код: ***

// Замена с использованием лямбды (динамическая замена)
val dynamicResult = regex.replace(text) { matchResult ->
    "[" + matchResult.value.toInt().toString() + "]"
}
println(dynamicResult) // Вывод: ID: [12345], код: [67890]

3. Группы захвата (capturing groups)

Группы захвата позволяют извлекать части совпадения. В Kotlin к группам можно обращаться по индексу или имени (если задано).

3.1. Доступ по индексу

val regex = Regex("""(\d{2})\.(\d{2})\.(\d{4})""") // дата в формате ДД.ММ.ГГГГ
val text = "Сегодня: 15.03.2024"
val match = regex.find(text)
if (match != null) {
    val (day, month, year) = match.destructured
    println("День: $day, Месяц: $month, Год: $year")
    // Вывод: День: 15, Месяц: 03, Год: 2024
}

3.2. Именованные группы

В Kotlin можно использовать именованные группы (синтаксис (?<name>...)).

val regex = Regex("""(?<username>\w+)@(?<domain>\w+\.\w+)""")
val text = "email: user@example.com"
val match = regex.find(text)
if (match != null) {
    val username = match.groups["username"]?.value
    val domain = match.groups["domain"]?.value
    println("Имя пользователя: $username, Домен: $domain")
    // Вывод: Имя пользователя: user, Домен: example.com
}

4. Практические примеры

Рассмотрим несколько реальных задач, которые часто встречаются при разработке на Kotlin.

4.1. Валидация email

fun isValidEmail(email: String): Boolean {
    val emailRegex = Regex("""^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$""")
    return emailRegex.matches(email)
}

println(isValidEmail("test@example.com"))   // true
println(isValidEmail("invalid-email"))      // false

4.2. Извлечение всех URL из текста

fun extractUrls(text: String): List<String> {
    val urlRegex = Regex("""https?://[^\s]+""")
    return urlRegex.findAll(text).map { it.value }.toList()
}

val text = "Посетите сайт https://pythonlib.ru и https://kotlinlang.org"
val urls = extractUrls(text)
println(urls) // [https://pythonlib.ru, https://kotlinlang.org]

4.3. Замена дат в тексте

fun formatDates(text: String): String {
    val dateRegex = Regex("""(\d{2})\.(\d{2})\.(\d{4})""")
    return dateRegex.replace(text) { match ->
        val (day, month, year) = match.destructured
        "$year-$month-$day" // переводим в формат ISO
    }
}

val text = "Дата: 15.03.2024, еще дата: 01.01.2025"
println(formatDates(text)) // Дата: 2024-03-15, еще дата: 2025-01-01

4.4. Проверка пароля на сложность

Блоги

Рекомендаций по книгам