我目前正在实施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) }
}
感谢。
修改
我可以将这两种模式与|
操作数“合并”,如下所示:
private let combinedPattern = "\\*{2}([\\w ]+)\\*{2}|\\_{1}([\\w ]+)\\_{1}"
但我的问题是要知道找到了哪个模式\\*{2}([\\w ]+)\\*{2}
或\\_{1}([\\w ]+)\\_{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])
}
}
}