Всем привет! Сегодня я собираюсь показать вам, как работать с Swift Regex, который был добавлен в Swift 5.7
Как мы работали с регулярными выражениями до Swift Regex?
До того как мы получили в свой арсенал Swift Regex, мы были вынуждены использовать следующее:
Методы, которые предоставляет NSString
・range(of:options:range:locale:)
・replacingOccurrences(of:with:options:range:)
・и т.д. …
Есть несколько причин, по которым я считаю, что NSRegularExpression
— не самый удобный в использовании инструмент.
Мы должны сразу использовать “try” уже только для создания инстанса класса
NSRegularExpression
, что непременно заставляет нас ожидать ситуации, когда возникают какие-либо ошибки.Чтобы написать регулярное выражение, нам нужно использовать двойные escape-символы.
Чтобы получить финального решения, мы должны использовать NSRange и Range.
Чтобы получить результат, нам необходима опциональная привязка (которую я пропустил в примере выше).
Но, к счастью, нам не нужно беспокоиться обо всем этом, если мы используем Swift Regex.
В чем заключаются преимущества Swift Regex по сравнению со старыми способами?
1. Литералы лаконичны; билдеры вносят структуру.
Swift Regex выглядит более интуитивно понятным благодаря своим билдерам регулярных выражений (в особенности resultBuilder
, который будет описан чуть позже).
Сравнение NSRegularExpression и Swift Regex:
2. Реальные парсеры как части регулярных выражений
Мы можем использовать уже существующие готовые парсеры (т.е.Date.ParseStrategy).
А также, мы можем использовать кастомные парсеры, если мы подготовим тип, соответствующий CustomConsumingRegexComponent.
3. Regex умеет в Unicode
Были реализованы следующие две фичи:
i: Каноническая эквивалентность
ii: Расширенные кластеры графем и классы символов со строками
4. Предсказуемое выполнение, очевидные элементы управления
Если мы будем использовать Swift Regex, мы сможем воспользоваться подсказками среды разработки и уменьшить количество ошибок во время компиляции!
Как работать со Swift Regex?
В нашем распоряжении есть три способа его использования.
1. Regex-литералы
Мы можем писать очень лаконично. На самом деле, нам больше не нужно использовать двойные escape-символы и беспокоиться о do-catch, как при работе с NSRegularExpression
.
2. Run-time конструкции
Эта фича может очень пригодится для полей поиска в редакторах или консольных утилит.
Если ввод Regex.init(_:) окажется невалидным, то мы получим ошибку времени выполнения. Типом вывода будет AnyRegexOutput. А значение мы можем извлечь следующим образом:
Мы можем извлечь результат с помощью extractValues(as:), но я не смог получить значение, когда пробовал использовать в качестве входных данных String.self
.
Если вам интересно, содержимое match.output было следующим:
AnyRegexOutput(input: “2023–03–20”, _elements: [_StringProcessing.AnyRegexOutput.ElementRepresentation(optionalDepth: 0, content: Optional((range: Range(Swift.String.Index(_rawBits: 15)..<Swift.String.Index(_rawBits: 655367)), value: nil)), name: nil, referenceID: nil)])
3. Regex-билдеры
Лично я считаю, что это самая хорошо структурированная форма написания регулярных выражений, доступная в Swift.
Это также наиболее интуитивно понятная форма с точки зрения чтения. И, конечно же, нам больше не нужна куча всяких мелочей, необходимых для NSRegularExpression
А причина, по которой мы можем писать Regex таким интуитивно понятным способом, — это resultBuilder
. Ниже приведена его реализация:
Некоторые типы, которые мы можем использовать для создания Regex
На сегодня мне осталось только показать вам некоторые типы, которые соответствуют RegexComponent. Мы можем использовать эти типы для создания инстансов Regex.
One
Это тип нужен, чтобы подтвердить, что во входных данных есть только одно вхождение указанного символа (то есть date(:locale:timeZone:calendar:)
в примере ниже).
Если их 0 или более 2, содержание “match” будет nil
.
ZeroOrMore
Этот тип нужен, чтобы подтвердить, что нет других символов, кроме указанного. Таким образом, даже если указанных символов нет, все в порядке.
Как использовать ZeroOrMore.
OneOrMore
Это тип нужен, чтобы подтвердить, что существует более одного указанного символа. Таким образом, если нет указанных символов, содержимое “match” будет nil
.
Repeat
Это тип, подтверждающий наличие указанного количества указанных символов.
Capture
Если мы воспользуемся Capture, мы сможем извлечь каждое значение из указанного ключа.
Нам не нужно указывать тип каждого ключа, если мы используем Regex-литералы.
TryCapture
Если мы используем TryCapture, мы можем преобразовать захваченное значение и конвертировать его!
Возможности Xcode
Вы можете автоматически конвертировать Regex-билдеры в Regex-литералы, как показано ниже. Таким образом, даже если вы не знакомы с Regex-билдерами, то вам не о чем беспокоиться!
Ссылки
Сегодня состоится открытое занятие "Поддержка многоязычности в приложениях iOS".
На уроке начнем с того, как обстоят дела со стандартной локализацией строк в типовом проекте под iOS, какие проблемы могут встретится при разработке и тестирования приложения. Узнаем, как эти проблемы решаются инструментами кодогенерации SwiftGen, R.swift, поговорим о различиях и о том, как их настроить для строк. Узнаем, что такое плюрализм и как его использовать для того, чтобы перевод строк был менее топорным.
Обсудим инструмент Localinter как решение, позволяющее автоматизировать ревью строковых констант. Рассмотрим различные способы и платформы для профессиональных переводов строк. Под конец спикер даст еще полезной информации, куда копать в реализации многонациональных приложений с учетом региональных различий.
Записаться можно на странице курса iOS Developer. Professional.