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

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

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

Начать курс

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

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

Статья будет полезна как новичкам, только знакомящимся со Swift, так и опытным разработчикам, желающим углубить знания по работе с текстом в iOS/macOS приложениях.

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

Класс NSRegularExpression — основной инструмент для работы с регулярными выражениями в Swift. Он предоставляет методы для поиска, замены и извлечения данных из строк.

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

Для создания объекта NSRegularExpression используется инициализатор, который принимает строку с шаблоном и опциональные флаги (NSRegularExpression.Options). Конструкция обёрнута в try, так как может выбросить ошибку при некорректном синтаксисе шаблона.

import Foundation

let pattern = "\\d{3}-\\d{2}-\\d{4}" // Пример: 123-45-6789
do {
    let regex = try NSRegularExpression(pattern: pattern, options: [])
    print("Регулярное выражение создано успешно")
} catch {
    print("Ошибка в синтаксисе регулярного выражения: \(error.localizedDescription)")
}

1.2. Основные опции (NSRegularExpression.Options)

Опции позволяют изменить поведение регулярного выражения. Вот наиболее часто используемые:

  • .caseInsensitive — игнорирование регистра символов (A = a).
  • .allowCommentsAndWhitespace — игнорировать пробелы и комментарии в шаблоне.
  • .dotMatchesLineSeparators — точка (.) также соответствует символам переноса строки.
  • .anchorsMatchLines — символы ^ и $ соответствуют началу и концу каждой строки, а не всей строки.

Пример с опцией .caseInsensitive:

let pattern = "hello"
let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let testString = "Hello, World!"
let range = NSRange(location: 0, length: testString.utf16.count)
if regex.firstMatch(in: testString, options: [], range: range) != nil {
    print("Найдено совпадение") // Выведет: Найдено совпадение
}

2. Поиск совпадений и работа с результатами

После создания регулярного выражения можно выполнять поиск совпадений в строке. Для этого используются методы firstMatch и matches.

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

Метод firstMatch(in:options:range:) возвращает первое найденное совпадение в виде объекта NSTextCheckingResult (или nil, если ничего не найдено).

let text = "Мой номер: 123-45-6789, а также 987-65-4321"
let pattern = "\\d{3}-\\d{2}-\\d{4}"
let regex = try NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(location: 0, length: text.utf16.count)

if let match = regex.firstMatch(in: text, options: [], range: range) {
    let matchedString = (text as NSString).substring(with: match.range)
    print("Первое совпадение: \(matchedString)") // 123-45-6789
}

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

Метод matches(in:options:range:) возвращает массив всех совпадений. Это полезно, когда нужно обработать каждое вхождение шаблона.

let text = "Коды: ABC-123, DEF-456, GHI-789"
let pattern = "[A-Z]{3}-\\d{3}"
let regex = try NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(location: 0, length: text.utf16.count)
let matches = regex.matches(in: text, options: [], range: range)

for match in matches {
    let code = (text as NSString).substring(with: match.range)
    print("Найден код: \(code)")
}
// Вывод:
// Найден код: ABC-123
// Найден код: DEF-456
// Найден код: GHI-789

2.3. Извлечение групп (capture groups)

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

let text = "Имя: Иван, возраст: 25"
let pattern = "Имя: (\\w+), возраст: (\\d+)"
let regex = try NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(location: 0, length: text.utf16.count)

if let match = regex.firstMatch(in: text, options: [], range: range) {
    let nameRange = match.range(at: 1)
    let ageRange = match.range(at: 2)
    
    let name = (text as NSString).substring(with: nameRange)
    let age = (text as NSString).substring(with: ageRange)
    print("Имя: \(name), возраст: \(age)") // Имя: Иван, возраст: 25
}

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

Класс NSRegularExpression предоставляет два метода для замены: stringByReplacingMatches (возвращает новую строку) и replaceMatches (изменяет исходную NSMutableString).

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

Пример замены всех номеров телефонов на текст "[СКРЫТО]":

let originalText = "Позвоните по номеру 123-45-6789 или 987-65-4321"
let pattern = "\\d{3}-\\d{2}-\\d{4}"
let regex = try NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(location: 0, length: originalText.utf16.count)

let modifiedText = regex.stringByReplacingMatches(
    in: originalText,
    options: [],
    range: range,
    withTemplate: "[СКРЫТО]"
)
print(modifiedText) // Позвоните по номеру [СКРЫТО] или [СКРЫТО]

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

Можно ссылаться на группы в шаблоне замены с

Блоги

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