Українська
Регулярні вирази та перевірка
Regex: повний збіг і пошук
Regex(pattern) описує правило тексту. matches перевіряє весь рядок; find шукає перший фрагмент; findAll дає всі неперекривні збіги. Плутанина між перевіркою всього вводу й пошуком усередині нього є поширеною помилкою валідації.
Клас символів [0-9] задає цифру, {3} – рівно три повторення, + – один або більше, ? – необов’язковість попереднього елемента. Дужки створюють групи, доступні через groupValues. Нульова група містить повний збіг, наступні – захоплені частини.
У звичайному Kotlin-рядку backslash доводиться екранувати, тому регулярний вираз для цифр може виглядати як "\\d+". У raw-рядку з потрійними лапками backslash не подвоюють. Функція Regex.escape потрібна, коли текст користувача має стати буквальним фрагментом шаблону, а не новим regex-кодом.
Приклад 4. Картка користувача
Перевіряється лише навчальний формат міжнародного телефонного номера: плюс і 12 ASCII-цифр, що починаються на 380. Це не доводить існування номера або належність оператору. Програма формує багаторядкову картку з визначеними полями.
kotlin
val phonePattern = Regex("\\+380[0-9]{9}")
fun userCard(name: String, phone: String, width: Int = 12): String {
require(name.isNotBlank())
require(phonePattern.matches(phone)) { "invalid phone format" }
require(width in 6..30)
return """
|${"Name".padEnd(width)}: ${name.trim()}
|${"Phone".padEnd(width)}: $phone
""".trimMargin()
}
fun main() {
println(userCard("Ada", "+380501112233", width = 6))
val versionPattern = Regex("([0-9]+)\\.([0-9]+)")
val match = versionPattern.find("version 2.4 ready")
if (match != null) {
println("major=${match.groupValues[1]}")
println("minor=${match.groupValues[2]}")
}
println(phonePattern.matches("x+380501112233"))
}text
Name : Ada
Phone : +380501112233
major=2
minor=4
falseЗнімок екрана
IntelliJ IDEA Alt+Enter > Check RegExp for phonePattern; show valid and prefixed-invalid samples.
Рис. 3.7. Перевірка повного збігу регулярного виразу на зразках.
Великий regex не завжди кращий за кілька простих перевірок. Формат дати може відповідати шаблону, але 31 лютого все одно не є календарною датою. Аналогічно номер із правильними символами може мати неправильну контрольну суму. Розділяйте перевірку синтаксису й перевірку змісту.
Перевірка функцій і текстових контрактів
Кожна функція повинна мати щонайменше нормальний і граничний приклад. Для тексту додайте порожній рядок, пробіли, неправильний роздільник і зайвий префікс. Для чисел перевірте нуль, межу, неправильний формат і значення, що не вміщується в тип.
Для форматування очікуваний рядок порівнюють цілком, включно з пробілами й переносами. Візуально схожі рядки можуть мати різну кількість пробілів або різні символи переносу. Позначення довжини й виведення в квадратних дужках допомагає налагодженню.
Рекурсивний алгоритм перевіряють від базового випадку до невеликого набору, який можна обчислити вручну. Для хвостової рекурсії пояснюють, чому після виклику не залишається додаткової роботи. Не запускайте навмисно нескінченну рекурсію як звичайний тест правильності: достатньо аналізу зменшення аргументу й межі.
Для розширення перевіряють і звичайний виклик через крапку, і випадки, які здаються «методними», але насправді мають статичне розв’язання. Розширення повинно робити поведінку зрозумілою, а не створювати враження, що змінено реалізацію стандартного класу.