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

Swift中如何将UTF-8字节格式的Emoji代码转换为Emoji图标

在Swift中将UTF-8转义字符串转换为Emoji图标

我从WS API获取到了这样的字符串响应(Emoji以转义字符串形式传递):

let strTemp = "Hii \\xF0\\x9F\\x98\\x81"

我希望将它转换为带Emoji图标的形式:Hii 😁。我确认这个字符串是UTF-8格式的,也已经通过在线UTF-8解码工具成功得到了目标结果,但不清楚怎么在Swift里实现这个功能。我尝试参考了一些关于Swift编码解码Emoji的资料,但没能解决问题,希望能得到帮助。


解决方案

别担心,这个问题核心是把带有\x前缀的UTF-8字节转义序列还原成对应的Unicode字符,我给你提供两种可行的Swift实现方法:

方法一:正则表达式解析(兼容性强)

这种方法可以处理混合普通文本和\x转义序列的情况,通用度很高:

func decodeEscapedUTF8(_ input: String) -> String? {
    // 匹配所有\x开头的两位十六进制转义序列
    guard let regex = try? NSRegularExpression(pattern: "\\\\x([0-9a-fA-F]{2})", options: []) else {
        return nil
    }
    
    let inputNSString = input as NSString
    var bytes = [UInt8]()
    var currentPosition = 0
    
    // 遍历所有匹配的转义序列
    regex.enumerateMatches(in: input, range: NSRange(location: 0, length: input.utf16.count)) { match, _, _ in
        guard let match = match else { return }
        
        // 添加转义序列之前的普通文本字节
        let prefixRange = NSRange(location: currentPosition, length: match.range.location - currentPosition)
        if prefixRange.length > 0 {
            let prefix = inputNSString.substring(with: prefixRange)
            bytes.append(contentsOf: prefix.utf8)
        }
        
        // 解析十六进制转义为UInt8字节
        let hexString = inputNSString.substring(with: match.range(at: 1))
        if let byte = UInt8(hexString, radix: 16) {
            bytes.append(byte)
        }
        
        currentPosition = match.range.location + match.range.length
    }
    
    // 添加最后一段普通文本
    if currentPosition < inputNSString.length {
        let suffix = inputNSString.substring(from: currentPosition)
        bytes.append(contentsOf: suffix.utf8)
    }
    
    // 将字节数组转为UTF-8字符串
    return String(data: Data(bytes), encoding: .utf8)
}

// 测试
let strTemp = "Hii \\xF0\\x9F\\x98\\x81"
if let decodedString = decodeEscapedUTF8(strTemp) {
    print(decodedString) // 输出: Hii 😁
}

方法二:简化版(仅处理纯转义Emoji场景)

如果你的字符串里只有\x转义的Emoji,没有其他复杂的混合文本,或者转义序列是连续的,可以用更简洁的方式:

func simpleDecodeEmoji(_ input: String) -> String? {
    // 去掉前缀的"Hii ",提取转义部分(可根据实际场景调整)
    let escapedPart = input.replacingOccurrences(of: "Hii ", with: "")
    // 替换\x为空格,分割成十六进制字符串数组
    let hexStrings = escapedPart.replacingOccurrences(of: "\\x", with: " ").split(separator: " ")
    // 转换为UInt8字节数组
    let bytes = hexStrings.compactMap { UInt8($0, radix: 16) }
    // 拼接回完整字符串
    return "Hii " + (String(data: Data(bytes), encoding: .utf8) ?? "")
}

// 测试
if let simpleResult = simpleDecodeEmoji(strTemp) {
    print(simpleResult) // 输出: Hii 😁
}

原理说明

你的原始字符串里的\xF0\x9F\x98\x81其实是😁这个Emoji的UTF-8字节转义表示:

  • F0 9F 98 81正是😁的UTF-8编码字节
  • 我们需要把这些转义的十六进制值还原成真实的字节,再通过Swift的String(data:encoding:)方法解码成对应的Unicode字符

内容的提问来源于stack exchange,提问作者Abhirajsinh Thakore

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:30:14