You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AttributedString中用正则匹配所有范围并设置属性?

解决AttributedString正则全匹配及属性设置问题

1. 获取所有匹配范围的正确方式

range(of:options:)确实只能返回第一个匹配项,要拿到所有符合<test>(.*?)</test>的范围,得用NSRegularExpression的全匹配能力。具体实现如下:

首先要把传入的AttributedString改为可变类型(原函数参数是不可变的let,无法修改属性),接着通过正则表达式找出所有匹配结果,再将每个结果的NSRange转换为AttributedString可识别的Range:

func testFunc(var attribString: AttributedString) -> AttributedString {
    // 示例输入:"Lorem ipsum dolor <test>first tag</test>sit Donec <test>second tag</test>"
    guard let regex = try? NSRegularExpression(pattern: "<test>(.*?)</test>") else {
        return attribString
    }
    
    // 转换为NSString适配NSRegularExpression的范围处理
    let nsString = NSString(string: String(attribString))
    let fullRange = NSRange(location: 0, length: nsString.length)
    
    // 获取所有匹配结果
    let matches = regex.matches(in: String(attribString), options: [], range: fullRange)
    
    // 遍历匹配结果,设置对应范围的属性
    for match in matches {
        let nsRange = match.range
        if let range = Range(nsRange, in: attribString) {
            attribString[range].foregroundColor = .red
        }
    }
    
    return attribString
}

2. 循环遍历设置属性的可行性

你提出的for range in ranges { attribString[range].foregroundColor = .red }方案完全可行,但要注意两个关键点:

  • 必须先一次性获取所有匹配范围,再遍历设置。虽然这里只是修改属性而非字符内容,但先拿到所有范围再处理能避免潜在的范围偏移问题。
  • 传入的attribString必须是可变的(var),原函数的不可变参数会导致修改属性时报错,必须调整参数类型。

额外提醒:如果你的AttributedString是Markdown解析后的结果,要确保正则匹配的是原始带标签的文本——如果Markdown已被解析为无标签的富文本,正则将无法匹配,此时需要在Markdown解析阶段就处理标签对应的样式。

内容的提问来源于stack exchange,提问作者Stefano Vet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:48:14