手动解析 \uXXXX 并将其转换为字符

提供String Extension自定义的 .decoded 方法:

var decoded: String {
    guard let data = self.data(using: .utf8),
          let decoded = String(data: data, encoding: .nonLossyASCII) else {
        return self
    }
    return decoded
}

问题在于:

  • String(data: ..., encoding: .nonLossyASCII) 只能解析通过 NSPropertyListSerialization 创建出来的 plist 风格字符串。
  • 在 iOS 16+,nonLossyASCII 对 Unicode 解码的支持变得不稳定,在 iOS 17/18 上经常会失败(尤其是非 plist 格式的字符串)。

✅ 正确做法(使用正则提取 + Unicode 转码)

我们可以手动解析 \uXXXX 并将其转换为字符:

extension String {
    /// 手动将 \\uXXXX 转换为 Unicode 字符(兼容 iOS 所有版本)
    var unicodeDecoded: String {
        let pattern = #"\\u([0-9a-fA-F]{4})"#
        let regex = try? NSRegularExpression(pattern: pattern, options: [])
        let nsString = self as NSString
        let results = regex?.matches(in: self, range: NSRange(location: 0, length: nsString.length)) ?? []
        
        var decoded = self
        for result in results.reversed() { // 从后往前替换避免位置错乱
            if let range = Range(result.range(at: 1), in: self) {
                let hex = String(self[range])
                if let scalar = UInt32(hex, radix: 16),
                   let unicodeScalar = UnicodeScalar(scalar) {
                    decoded.replaceSubrange(Range(result.range, in: decoded)!, with: String(unicodeScalar))
                }
            }
        }
        return decoded
    }
}

✅ 使用示例

let raw = "\\u60a8\\u597d\\uff0c\\u60a8\\u6240\\u63d0\\u95ee\\u7684\\u95ee\\u9898\\u6682\\u65f6\\u6ca1\\u6709\\u7b54\\u6848\\uff0c\\u8bf7\\u7a0d\\u540e\\u518d\\u8bd5\\u3002"
print(raw.unicodeDecoded)

🔚 输出:

您好,您所提问的问题暂时没有答案,请稍后再试。

💡总结

方法 状态 iOS 18.4
.nonLossyASCII ❌ 不稳定/失效
正则 + 手动 Unicode 解码 ✅ 稳定可靠
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容