代码之家  ›  专栏  ›  技术社区  ›  Abhirajsinh Thakore

将UTF-8(字节)emoji代码转换为文本形式的emoji图标

  •  -1
  • Abhirajsinh Thakore  · 技术社区  · 8 年前

    当WS-API以字符串形式发送emoji时,我将从下面的字符串中获取此响应:

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

    我想把它转换成这样的emoji图标-> Hii 😁

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

    我试过在网上用 UTF-8 Decoder

    我成功地破解了表情符号

    解码前:

    enter image description here

    解码后: enter image description here

    但这里的问题是我不知道如何迅速处理它。

    我提到了下面的链接,但它对我不起作用。

    Swift Encode/decode emojis

    任何帮助都将不胜感激。

    谢谢。

    2 回复  |  直到 8 年前
        1
  •  1
  •   TheTiger    8 年前

    因为你已经给出了转换器工具的链接 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);
    

    输出: 小精灵


    迅捷

    我可以转换 \\xF0\\x9F\\x98\\x81 😁 在里面 SWift . 首先我把六弦转换成 Data 然后回到 String 使用 UTF-8 编码。

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

    输出: __

    下面是我用来将十六进制字符串转换为数据的函数。我跟着去了 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)
    

    我做了一个字符串扩展,如果它有前缀,我每4个字符检查一次 \x 和计数 4 最后两个字符通过使用 radix 如上所述。

    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 ?? ""
        }
    }
    

    用途:

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

    嗨81

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

    欢迎来到SP19!

        2
  •  1
  •   Abdelahad Darwish    8 年前

    我解决了你的问题,但需要更多的工作才能使它成为一般性的问题,这里的问题是你的emijo代表了 Hex Byte x9F ,所以我们必须将这个十六进制转换为 utf8 然后将其转换为 Data 最后将数据转换为 String

    最终结果 Hii 😁 请阅读评论

     let strTemp = "Hii \\xF0\\x9F\\x98\\x81"
    
    
                let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
                // get all matched hex  xF0 , x9f,..etc
    
                let matches = regex.matches(in: strTemp, options: [], range: NSMakeRange(0, strTemp.count))
    
    
                // Data that will hanlde convert hex to UTf8
                var emijoData = Data(capacity: strTemp.count / 2)
    
                matches.enumerated().forEach { (offset , check) in
                    let byteString = (strTemp as NSString).substring(with: check.range)
                    var num = UInt8(byteString, radix: 16)!
                    emijoData.append(&num, count: 1)
                }
    
                let subStringEmijo = String.init(data: emijoData, encoding: String.Encoding.utf8)!
                //now we have your emijo text  😁 we can replace by its code from string using matched ranges `first` and `last`
    
                // All range range of  \\xF0\\x9F\\x98\\x81 in "Hii \\xF0\\x9F\\x98\\x81" to replce by your emijo
    
                if let start = matches.first?.range.location, let end = matches.last?.range.location  , let endLength = matches.last?.range.length {
    
                    let startLocation = start  - 2
                    let length = end - startLocation + endLength
    
                    let sub = (strTemp as NSString).substring(with: NSRange.init(location: startLocation, length: length))
    
                    print( strTemp.replacingOccurrences(of: sub, with: subStringEmijo))
                  // Hii 😁
    
                }