如何从Swift的AttributedString中提取各属性对应的原单词?
从Markdown生成的AttributedString中提取带样式的单词数组
我们需要遍历由Markdown构建的Swift AttributedString,根据文本的属性类型分别构建对应的单词数组。例如输入Markdown内容:
**bold** **moreBold** *italicText*
最终要得到:
let boldWords: [String] = ["bold", "moreBold"] let italicWords: [String] = ["italicText"]
完整实现代码
import Foundation import SwiftUI func word(for run: AttributedString.Run, in attributedStr: AttributedString) -> [String] { // 提取当前run对应的文本内容,转为String后返回数组 let targetSubstring = attributedStr[run.range] return [String(targetSubstring)] } // 示例使用 let markdown = "**bold** **moreBold** *italicText*" guard let attributedStr = try? AttributedString(markdown: markdown) else { fatalError("解析Markdown失败") } var boldWords: [String] = [] var italicWords: [String] = [] for run in attributedStr.runs { if let intent = run.inlinePresentationIntent { switch intent { case .emphasized: // 匹配斜体样式,收集对应单词 italicWords.append(contentsOf: word(for: run, in: attributedStr)) case .stronglyEmphasized: // 匹配加粗样式,收集对应单词 boldWords.append(contentsOf: word(for: run, in: attributedStr)) default: break } } } print("boldWords: \(boldWords)") print("italicWords: \(italicWords)")
关键说明
word(for:in:)函数通过run.range直接定位AttributedString中对应样式的文本范围,转换为String后返回数组。如果单个run包含多个空格分隔的单词,可在函数内添加分割逻辑(比如用components(separatedBy: .whitespaces)处理)。- 遍历
attributedStr.runs时,通过inlinePresentationIntent识别当前文本块的样式类型,将对应文本添加到目标数组。 - 实际开发中建议用
try?替代try!,避免Markdown解析失败时触发崩溃。
内容的提问来源于stack exchange,提问作者hkatz
相关产品推荐
相关产品推荐

