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

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

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

Начать курс

Введение в регулярные выражения в Swift

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

В этой статье мы разберем основные возможности работы с регулярными выражениями в Swift на практических примерах. Вы узнаете, как создавать шаблоны, выполнять поиск, замену и извлечение данных.

Основы работы с NSRegularExpression

Класс NSRegularExpression — основной способ работы с регулярными выражениями в Swift. Рассмотрим базовые операции.

Создание регулярного выражения

import Foundation

let pattern = "[A-Za-z]+@[A-Za-z]+\\.[A-Za-z]+"
guard let regex = try? NSRegularExpression(pattern: pattern) else {
    fatalError("Неверный шаблон")
}

Обратите внимание на двойной слеш \\ — в Swift строки требуют экранирования обратной косой черты.

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

let text = "Свяжитесь с нами по email: support@example.com"
let nsString = text as NSString
let range = NSRange(location: 0, length: nsString.length)

if let match = regex.firstMatch(in: text, range: range) {
    let email = nsString.substring(with: match.range)
    print("Найден email: \(email)") // support@example.com
}

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

let text = "Контакты: info@site.com, admin@site.com, support@site.com"
let matches = regex.matches(in: text, range: NSRange(location: 0, length: text.count))

for match in matches {
    let range = match.range
    let email = (text as NSString).substring(with: range)
    print(email)
}
// Вывод:
// info@site.com
// admin@site.com
// support@site.com

Использование групп захвата

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

Извлечение данных с помощью групп

let pattern = "(\\d{4})-(\\d{2})-(\\d{2})"
let dateString = "Сегодня: 2024-03-15"

guard let regex = try? NSRegularExpression(pattern: pattern) else { return }
let nsString = dateString as NSString

if let match = regex.firstMatch(in: dateString, range: NSRange(location: 0, length: nsString.length)) {
    let fullDate = nsString.substring(with: match.range) // 2024-03-15
    let year = nsString.substring(with: match.range(at: 1)) // 2024
    let month = nsString.substring(with: match.range(at: 2)) // 03
    let day = nsString.substring(with: match.range(at: 3)) // 15
    
    print("Год: \(year), Месяц: \(month), День: \(day)")
}

Именованные группы (работа с Range)

Начиная с Swift 5.7, можно использовать более удобный синтаксис с Range:

let text = "Цена: 1500 рублей"
let pattern = #"(\d+)\sрублей"#

if let range = text.range(of: pattern, options: .regularExpression) {
    let match = text[range]
    print("Найдено: \(match)") // 1500 рублей
}

Замена текста с помощью регулярных выражений

Одна из самых полезных возможностей — замена частей текста по шаблону.

Простая замена

let text = "Позвоните по номеру +7 (123) 456-78-90"
let pattern = "\\+7\\s\\(\\d{3}\\)\\s\\d{3}-\\d{2}-\\d{2}"
let replacement = "[номер скрыт]"

guard let regex = try? NSRegularExpression(pattern: pattern) else { return }
let modifiedText = regex.stringByReplacingMatches(
    in: text,
    range: NSRange(location: 0, length: text.count),
    withTemplate: replacement
)

print(modifiedText) // Позвоните по номеру [номер скрыт]

Замена с использованием групп

let text = "Иванов Иван, Петров Петр, Сидоров Алексей"
let pattern = "(\\w+)\\s(\\w+)"
let replacement = "$2 $1" // меняем фамилию и имя местами

guard let regex = try? NSRegularExpression(pattern: pattern) else { return }
let result = regex.stringByReplacingMatches(
    in: text,
    range: NSRange(location: 0, length: text.count),
    withTemplate: replacement
)

print(result) // Иван Иванов, Петр Петров, Алексей Сидоров

Практические примеры для iOS/macOS

Валидация email в UITextField

func isValidEmail(_ email: String) -> Bool {
    let emailPattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format: "SELF MATCHES %@", emailPattern)
    return emailPredicate.evaluate(with: email)
}

// Использование
let emailField = UITextField()
emailField.text = "user@example.com"

if isValidEmail(emailField.text ?? "") {
    print("Email валидный")
} else {
    print("Неверный формат email")
}

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

func extractURLs(from text: String) -> [String] {
    let pattern = "https?://[\\w./?=&%-]+"
    guard let regex = try? NSRegularExpression(pattern: pattern) else { return [] }
    
    let nsString = text as NSString
    let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
    
    return results.map { nsString.substring(with: $0.range) }
}

let text = "Посетите сайт https://example.com или https://pythonlib.ru"
let urls = extractURLs(from: text)
print(urls) // ["https://example.com", "https://pythonlib.ru"]

Фильтрация и очистка текста

func removeHTMLTags(from html: String) -> String {
    let pattern = "<[^>]+>"
    guard let regex = try? NSRegularExpression(pattern: pattern) else { return html }
    
    return regex.stringByReplacingMatches(
        in: html,
        range: NSRange(location: 0, length: html.count),
        withTemplate: ""
    )
}

let htmlString = "<p>Привет, <b>мир</b>!</p>"
let cleanText = removeHTMLTags(from: htmlString)
print                

Блоги

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