使用|找到了哪个NSRegularExpression 操作者
我目前正在实现NSRegularExpressions
来检查项目中UITextView
字符串中的模式。
模式检查和操作按预期工作; 例如:我正在尝试找到常规**bold**
降价模式,如果我找到它,我会应用一些归因于该范围的文本,并且它按预期工作。
我遇到了一个问题。 我不知道如何一次运行多个模式,并为找到的每个模式应用不同的操作。
在我的UITextView
委托shouldChangeTextIn range: NSRange
或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) } }
谢谢。
编辑
我可以将两个模式“合并”到|
操作数如下:
private let combinedPattern = "\\*{2}([\\w ]+)\\*{2}|\\_{1}([\\w ]+)\\_{1}"
但我的问题是要知道哪个模式找到了\\*{2}([\\w ]+)\\*{2}
一个或\\_{1}([\\w ]+)\\_{1}
如果使用组合模式,则结果将在匹配结果的不同范围内。
如果要访问第一个捕获组(粗体模式),则需要访问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]) } } }