Какое NSRegularExpression было найдено с помощью |оператор - PullRequest
0 голосов
/ 14 мая 2018

В настоящее время я реализую NSRegularExpressions для проверки шаблонов внутри строки UITextView в моем проекте.

Проверка шаблонов и операции работают должным образом; Например: я пытаюсь найти обычный шаблон уценки **bold**, и если я его нахожу, я применяю некоторый текст, относящийся к диапазону, и он работает как ожидалось.

Хотя я столкнулся с проблемой. Я не знаю, как запускать несколько шаблонов одновременно и применять разные операции для каждого найденного шаблона.

В моем UITextView делегате textViewDidChange или shouldChangeTextIn range: NSRange я запускаю проверку жирным шрифтом \\*{2}([\\w ]+)\\*{2}, но затем я также запускаю проверку шаблона курсива \\_{1}([\\w ]+)\\_{1}, повторяя цикл через UITextView text.

Я реализовал следующую пользовательскую функцию, которая применяет переданную в regex к строке, но мне нужно вызывать эту функцию несколько раз, чтобы проверить каждый шаблон, поэтому я бы хотел поставить проверку шаблона в один сингл, затем "разбирать" каждый match.

fileprivate func regularExpression(regex: NSRegularExpression, type: TypeAttributes) {
    let str = inputTextView.attributedText.string
    let results = regex.matches(in: str, range: NSRange(str.startIndex..., in: str))
    _ = results.map { self.applyAttributes(range: $0.range, type: type) }
}

Спасибо.

EDIT

Я могу «объединить» оба шаблона с операндом | следующим образом:

private let combinedPattern = "\\*{2}([\\w ]+)\\*{2}|\\_{1}([\\w ]+)\\_{1}"

но моя проблема в том, чтобы узнать, какой шаблон был найден \\*{2}([\\w ]+)\\*{2} один или \\_{1}([\\w ]+)\\_{1}

1 Ответ

0 голосов
/ 14 мая 2018

Если вы используете комбинированный шаблон, у вас будут результаты в другом диапазоне результатов матча.

Если вы хотите получить доступ к первой группе захвата (жирный шрифт), вам нужно получить доступ к диапазону в 1. Когда совпадение совпадает со второй группой, у вас будет первая с недопустимым диапазоном, поэтому вам нужно проверить, если это действует не так:

results.forEach {
    var range = $0.range(at: 1)
    if range.location + range.length < str.count {
         self.applyAttributes(range: range, type: .bold)
    }
    range = $0.range(at: 2)
    if range.location + range.length < str.count {
        self.applyAttributes(range: range, type: .italic)
    }
}

После этого вы можете расширить перечисление TypeAttributes, чтобы оно возвращало индексный диапазон, связанный с вашим регулярным выражением:

extension NSRange {
    func isValid(for string:String) -> Bool {
        return location + length < string.count
    }
}

let attributes: [TypeAttributes] = [.bold, .italic]

results.forEach { match in
    attributes.enumerated().forEach { index, attribute in
         let range = match.range(at: index+1)
         if range.isValid(for: str) {                
             self.applyAttributes(range: range, type: attribute[index]) 
         }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...