使用|找到了哪个NSRegularExpression操作者

时间:2018-05-14 08:38:16

标签: ios swift nsregularexpression

我目前正在实施NSRegularExpressions来检查项目中UITextView字符串中的模式。

模式检查和操作按预期工作;例如:我正在尝试找到常规的**bold**降价模式,如果找到它,我会应用一些属于该范围的文本,并且它会按预期工作。

我遇到了一个问题。我不知道如何一次运行多个模式,并为找到的每个模式应用不同的操作。

在我的UITextView代理textViewDidChangeshouldChangeTextIn 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) }
}

感谢。

修改

我可以将这两种模式与|操作数“合并”,如下所示:

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

但我的问题是要知道找到了哪个模式\\*{2}([\\w ]+)\\*{2}\\_{1}([\\w ]+)\\_{1}

1 个答案:

答案 0 :(得分:2)

如果使用组合模式,则结果将在匹配结果的不同范围内。

如果你想访问第一个捕获组(粗体模式),你需要访问1的范围。当匹配第二组时,你将得到第一个无效范围,所以你需要检查它是否& #39;有效的不是这样的:

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]) 
         }
    }
}