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

Swift求助:如何快速将大量长HTML格式消息转为纯文本?

快速将HTML转换为纯文本的Swift解决方案

你当前使用NSAttributedString解析HTML的方式,底层依赖WebKit引擎,处理大量长文本时性能开销极大。以下是两种更高效的纯文本提取方案:

方法1:XMLParser原生解析(推荐,可靠且高效)

利用系统原生的XMLParser(HTML可兼容XML解析),逐节点提取文本内容,避免WebKit的重量级解析流程,适合复杂HTML结构的批量处理。

extension String {
    func htmlToPlainText() -> String {
        let parser = XMLParser(data: self.data(using: .utf8) ?? Data())
        let delegate = HTMLTextParserDelegate()
        parser.delegate = delegate
        parser.parse()
        return delegate.plainText.trimmingCharacters(in: .whitespacesAndNewlines)
    }
}

class HTMLTextParserDelegate: NSObject, XMLParserDelegate {
    private(set) var plainText = ""
    
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
        if !trimmed.isEmpty {
            plainText += trimmed + " "
        }
    }
    
    // 处理换行标签,保留文本换行逻辑
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        if elementName.lowercased() == "br" || elementName.lowercased() == "p" {
            plainText += "\n"
        }
    }
}

使用示例:

let htmlContent = "<p>这是一段<b>带格式</b>的HTML消息<br>第二行内容</p>"
let plainText = htmlContent.htmlToPlainText()
// 输出:"这是一段 带格式 的HTML消息\n第二行内容"

方法2:正则表达式快速清理(适合简单HTML场景)

如果你的HTML结构简单(无复杂嵌套、无特殊实体),可以用正则直接替换所有HTML标签,速度最快。

extension String {
    func simpleHtmlToPlainText() -> String {
        // 移除所有HTML标签
        let tagRegex = try? NSRegularExpression(pattern: "<[^>]+>", options: .caseInsensitive)
        let tagFreeText = tagRegex?.stringByReplacingMatches(
            in: self,
            options: [],
            range: NSRange(location: 0, length: self.utf16.count),
            withTemplate: ""
        ) ?? self
        
        // 替换常见HTML实体
        return tagFreeText
            .replacingOccurrences(of: "&amp;", with: "&")
            .replacingOccurrences(of: "&lt;", with: "<")
            .replacingOccurrences(of: "&gt;", with: ">")
            .replacingOccurrences(of: "&quot;", with: "\"")
            .trimmingCharacters(in: .whitespacesAndNewlines)
    }
}

使用示例:

let simpleHtml = "<div>简单<b>加粗</b>内容</div>"
let plainText = simpleHtml.simpleHtmlToPlainText()
// 输出:"简单加粗内容"

额外优化建议

  1. 后台队列处理:把解析逻辑放到后台队列执行,避免阻塞主线程:
func processHtmlToPlainText(_ html: String, completion: @escaping (String) -> Void) {
    DispatchQueue.global(qos: .background).async {
        let result = html.htmlToPlainText()
        DispatchQueue.main.async {
            completion(result)
        }
    }
}
  1. 缓存结果:如果同一HTML内容会重复处理,建议缓存转换后的纯文本,减少重复计算。

内容的提问来源于stack exchange,提问作者Marta Paniti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:05:13