将UTF-8(字节)表情符号代码转换为表情符号图标作为文本

时间:2018-05-18 10:21:41

标签: swift emoji

当我们将表情符号作为字符串发送时,我将以下字符串作为WS API的响应:

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

我想将它转换为这样的表情符号图标 - > Hii

我认为它是以UTF-8格式提供的,如下图所示:Image Unicode enter image description here

  

我尝试使用UTF-8 Decoder

在线解码

我得到了表情符号成功解码

解码前:

enter image description here

解码后 enter image description here

但问题是我不知道如何在Swift中使用它。

我提到了以下链接,但它对我没用。

  

Swift Encode/decode emojis

任何帮助都将不胜感激。

感谢。

2 个答案:

答案 0 :(得分:1)

正如您已经给出转换器工具的链接,它显然正在进行UTF-8编码和解码。您有UTF-8个编码字符串,因此这里是UTF8-Decoding的示例。

<强>目标C

const char *ch = [@"Hii \xF0\x9F\x98\x81" cStringUsingEncoding:NSUTF8StringEncoding];
NSString *decode_string = [NSString stringWithUTF8String:ch];
NSLog(@"%@",decode_string);
  

输出: Hii

Swift

我可以在\\xF0\\x9F\\x98\\x81中将转换为SWift。 首先,我将hexa字符串转换为Data,然后使用String编码返回UTF-8

var str = "\\xF0\\x9F\\x98\\x81"
if let data = data(fromHexaStr: str) {
     print(String(data: data, encoding: String.Encoding.utf8) ?? "")
}
  

输出

下面是我用来将hexa字符串转换为数据的函数。我跟着this answer

func data(fromHexaStr hexaStr: String) -> Data? {
    var data = Data(capacity: hexaStr.characters.count / 2)
    let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
    regex.enumerateMatches(in: hexaStr, range: NSMakeRange(0, hexaStr.utf16.count)) { match, flags, stop in
        let byteString = (hexaStr as NSString).substring(with: match!.range)
        var num = UInt8(byteString, radix: 16)!
        data.append(&num, count: 1)
    }

    guard data.count > 0 else { return nil }

    return data
}

注意: 上述代码的问题是它只转换六角形字符串而不是组合字符串。

最终工作解决方案:SWIFT

我通过使用for循环代替[0-9a-f]{1,2}正则表达式来完成此操作,因为这也会扫描81, 9F, Any Two digits number,这显然是错误的。

例如:I have 81 INR \\xF0\\x9F\\x98\\x81

/// This line will convert "F0" into hexa bytes
let byte = UInt8("F0", radix: 16)

我做了一个String扩展,如果它有前缀\x和count 4,我会检查每4个字符,并且如前所述,使用radix可以将最后两个字符转换为hexa字节上方。

extension String {

    func hexaDecoededString() -> String {

        var newData = Data()
        var emojiStr: String = ""
        for char in self.characters {

            let str = String(char)
            if str == "\\" || str.lowercased() == "x" {
                emojiStr.append(str)
            }
            else if emojiStr.hasPrefix("\\x") || emojiStr.hasPrefix("\\X") {
                emojiStr.append(str)
                if emojiStr.count == 4 {
                    /// It can be a hexa value
                    let value = emojiStr.replacingOccurrences(of: "\\x", with: "")
                    if let byte = UInt8(value, radix: 16) {
                        newData.append(byte)
                    }
                    else {
                        newData.append(emojiStr.data(using: .utf8)!)
                    }
                    /// Reset emojiStr
                    emojiStr = ""
                }
            }
            else {
                /// Append the data as it is
                newData.append(str.data(using: .utf8)!)
            }
        }

        let decodedString = String(data: newData, encoding: String.Encoding.utf8)
        return decodedString ?? ""
    }
}

<强> USAGE:

var hexaStr = "Hi \\xF0\\x9F\\x98\\x81 81"
print(hexaStr.hexaDecoededString())
  

你好81

hexaStr = "Welcome to SP19!\\xF0\\x9f\\x98\\x81"
print(hexaStr.hexaDecoededString())
  

欢迎来到SP19!

答案 1 :(得分:1)

我已修复您的问题,但需要更多工作才能使其更加通用,此处的问题是您的Emijo由Hex Byte x9F代表,因此我们必须将此Hex转换为{{1}然后将其转换为utf8,最后将数据转换为Data

最终结果String 请阅读评论

Hii