【问题标题】:Which NSRegularExpression was found using the | operator使用 | 找到了哪个 NSRegularExpression操作员
【发布时间】:2023-03-23 11:34:01
【问题描述】:

我目前正在实施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}

【问题讨论】:

  • 您将在您搜索的同一范围或其他部分应用这两种模式
  • 相同范围,全文。我可以用 | 操作数“合并”两个模式,但我不知道在迭代 .matches 时哪个匹配是什么
  • 不相关,但调用map 然后丢弃结果是没有意义的。如果您只是想遍历一个集合并对其所有值应用闭包而不返回任何内容,请使用forEach 而不是map。
  • @DávidPásztor 你是对的,我已经根据 Martin R. 之前的回答实现了这个,无论如何我会在解决这个问题时修复它:)
  • 老实说,我不确定您是否想将其组合成一个表达式。我担心你想同时匹配两者,即使它们重叠但 | 只会匹配其中一个。此外,您可能应该在模式中包含所有空格字符 \s,而不仅仅是单个空格。另外,我很确定_ 包含在\w 中,因此您应该特别排除它[\\w\\s^_]。

标签: ios swift nsregularexpression


【解决方案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]) 
         }
    }
}

【讨论】:

  • 哇!我不知道这是可能的。我目前不在我的机器前测试这个,但我会尽快测试它并反馈给你。看起来这将解决我的问题。谢谢!
  • 当然!告诉我它是否有效!我刚刚编辑了答案以将枚举映射添加到结果中。
  • 这个扩展真的让一切变得轻松。有了它,我就可以插入任何属性,然后检查它们并对其应用更改。相当令人印象深刻。期待对此进行测试,但我 100% 确定它会起作用。非常感谢
  • 请注意,key+1 应该是 index+1?
  • 你能查一下this。不知何故,它混淆了一些属性
猜你喜欢
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多