Регулярные выражения в Swift с примерами: для начинающих

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

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

Начать курс

Регулярные выражения в Swift: полное руководство для новичков

Регулярные выражения (regex) — это мощный инструмент для поиска, замены и валидации текстовых данных. В Swift работа с регулярными выражениями реализована через класс NSRegularExpression из фреймворка Foundation. В этой статье вы научитесь создавать и применять регулярные выражения в приложениях для iOS и macOS, разберете реальные примеры и освоите основы синтаксиса.

1. Основы синтаксиса регулярных выражений

Прежде чем писать код на Swift, важно понять базовые символы и конструкции regex. Вот ключевые элементы:

  • . — любой символ (кроме перевода строки)
  • * — 0 или более повторений предыдущего символа
  • + — 1 или более повторений
  • ? — 0 или 1 повторение (делает предыдущий символ необязательным)
  • \d — любая цифра (0-9)
  • \w — любая буква, цифра или подчеркивание
  • [abc] — один из символов a, b или c
  • [^abc] — любой символ, кроме a, b, c
  • ^ — начало строки
  • $ — конец строки

Эти символы комбинируются для создания шаблонов. Например, шаблон ^[A-Za-z]+$ означает: строка состоит только из букв латинского алфавита от начала до конца.

2. Создание и использование NSRegularExpression в Swift

В Swift работа с regex начинается с импорта Foundation и создания экземпляра NSRegularExpression. Рассмотрим простой пример: поиск всех цифр в строке.

import Foundation

let text = "Мой номер: 123-456-7890"
let pattern = "\\d+" // шаблон: одна или более цифр

do {
    let regex = try NSRegularExpression(pattern: pattern)
    let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text))
    
    for match in results {
        if let range = Range(match.range, in: text) {
            print("Найдено: \(text[range])")
        }
    }
} catch {
    print("Ошибка в регулярном выражении: \(error.localizedDescription)")
}
// Вывод:
// Найдено: 123
// Найдено: 456
// Найдено: 7890

Обратите внимание на экранирование обратной косой черты: в Swift строке "\\d" соответствует регулярному выражению \d. Класс NSRegularExpression выбрасывает исключение при неверном шаблоне, поэтому используем try-catch.

2.1. Работа с NSRange

Метод matches(in:range:) возвращает массив объектов NSTextCheckingResult. Каждый результат содержит диапазон (NSRange) найденного совпадения. Для преобразования в Swift Range используйте инициализатор Range(match.range, in: text).

3. Практические примеры регулярных выражений

Рассмотрим три типичные задачи: проверка email, извлечение URL и замена текста.

3.1. Валидация email-адреса

Проверим, соответствует ли строка простому шаблону email (упрощенный вариант):

func isValidEmail(_ email: String) -> Bool {
    let pattern = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$"
    let regex = try? NSRegularExpression(pattern: pattern)
    let range = NSRange(location: 0, length: email.utf16.count)
    return regex?.firstMatch(in: email, range: range) != nil
}

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

Здесь мы используем firstMatch, который возвращает первое совпадение. Если совпадений нет — возвращается nil.

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

Допустим, у нас есть строка с несколькими ссылками. Извлечем все URL:

let text = "Посетите сайт https://pythonlib.ru или напишите на support@pythonlib.ru"
let pattern = "https?://[\\w./%-]+"

do {
    let regex = try NSRegularExpression(pattern: pattern)
    let matches = regex.matches(in: text, range: NSRange(text.startIndex..., in: text))
    
    var urls: [String] = []
    for match in matches {
        if let range = Range(match.range, in: text) {
            urls.append(String(text[range]))
        }
    }
    print("Найденные URL: \(urls)")
} catch {
    print("Ошибка: \(error)")
}
// Вывод: Найденные URL: ["https://pythonlib.ru"]

Обратите внимание: шаблон https?:// соответствует как http://, так и https://. Символ ? делает букву 's' необязательной.

3.3. Замена текста с помощью regex

Метод stringByReplacingMatches позволяет заменить все совпадения на указанную строку:

let originalText = "Сегодня 15.03.2024, а завтра 16.03.2024"
let pattern = "(\\d{2})\\.(\\d{2})\\.(\\d{4})"
let replacement = "$3-$2-$1" // меняем формат на ГГГГ-ММ-ДД

let regex = try? NSRegularExpression(pattern: pattern)
let modifiedText = regex?.stringByReplacingMatches(
    in: originalText,
    range: NSRange(originalText.startIndex..., in: originalText),
    withTemplate: replacement
) ?? originalText

print(modifiedText)
// Вывод: Сегодня 2024-03-15, а завтра 2024-03-16

В шаблоне используются группы захвата (круглые скобки). В строке замены $1, $2, $3 ссылаются на первую, вторую и третью группы соответственно. Это позволяет переставлять части даты.

4. Продвинутые возможности и советы

Вот несколько дополнительных аспектов, которые помогут вам эффективно работать с regex в Swift:

  • Опции регулярного выражения: Второй параметр NSRegularExpression — массив опций. Например, .caseInsensitive для игнорирования регистра, .dotMatchesLineSepar

Блоги

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