我需要将一些HTML转换为纯文本,并尝试了这里概述的方法:
Convert HTML to Plain Text in Swift
问题是在iOS 8.2上,NSAttributedString有一个错误,当HTML在后台线程上呈现为纯文本时,可能导致EXC_BAD_ACCESS崩溃(WebKit内部)。转换需要在后台线程上完成,因为它可以(并且通常会)需要一段时间。
所以我需要一个更原始的Swift解决方案,理想情况下是一个惯用的解决方案。
这也让我觉得这可能是那些具有优雅和整洁的功能解决方案的问题之一 - 它本质上是对String的filter()
操作吗?
答案 0 :(得分:2)
基本上我已经从here采用了解决方案并将其转换为Swift 3语法。
解决方案使用Scanner(以前的NSScanner)来查找"<"然后扫描到">"将所有内容考虑在内,将其保存到NSString变量中。
然后只需使用传递NSString变量的replacingOccurrences(of:with:)
这是最终功能的样子:
private func stripHTML(fromString rawString: String) -> String {
let scanner: Scanner = Scanner(string: rawString)
var text: NSString? = ""
var convertedString = rawString
while !scanner.isAtEnd {
scanner.scanUpTo("<", into: nil)
scanner.scanUpTo(">", into: &text)
convertedString = convertedString.replacingOccurrences(of: "\(text!)>", with: "")
}
return convertedString
}
答案 1 :(得分:1)
我提出的最佳解决方案是String扩展中的正则表达式,它足以处理我需要处理的HTML片段:
extension String {
func plainTextFromHTML() -> String? {
let regexPattern = "<.*?>"
var err: NSError?
if let stripHTMLRegex = NSRegularExpression(pattern: regexPattern, options: NSRegularExpressionOptions.CaseInsensitive, error: &err) {
let plainText = stripHTMLRegex.stringByReplacingMatchesInString(self, options: NSMatchingOptions.ReportProgress, range: NSMakeRange(0, count(self)), withTemplate: "")
return err == nil ? plainText : nil
} else {
println("Warning: failed to create regular expression from pattern: \(regexPattern)")
return nil
}
}
}
Swift 2.2
extension String {
func plainTextFromHTML() -> String? {
let regexPattern = "<.*?>"
do {
let stripHTMLRegex = try NSRegularExpression(pattern: regexPattern, options: NSRegularExpressionOptions.CaseInsensitive)
let plainText = stripHTMLRegex.stringByReplacingMatchesInString(self, options: NSMatchingOptions.ReportProgress, range: NSMakeRange(0, self.characters.count), withTemplate: "")
return plainText
} catch {
print("Warning: failed to create regular expression from pattern: \(regexPattern)")
return nil
}
}
}
然而,完整的HTML转换为纯文本需要更高级的解决方案。