将 UTF-8(字节)表情符号代码转换为表情符号图标作为文本
Convert UTF-8 (Bytes) Emoji Code to Emoji icon as a text
当 WS API 将表情符号作为字符串发送时,我收到以下字符串作为响应:
let strTemp = "Hii \xF0\x9F\x98\x81"
我想把它转换成这样的表情图标 -> Hii
我认为它以 UTF-8 格式出现,如下图所示:Image Unicode
I have tried decoding it Online using UTF-8 Decoder
表情成功解码
解码前:
解码后:
但这里的问题是我不知道如何在 Swift 中使用它。
我参考了 link 但它对我不起作用。
Swift Encode/decode emojis
如有任何帮助,我们将不胜感激。
谢谢。
正如您已经提供的 link 转换器工具,它显然在进行 UTF-8
编码和解码。您有 UTF-8
编码的字符串,所以这里是 UTF8-Decoding
.
的示例
Objective-C
const char *ch = [@"Hii \xF0\x9F\x98\x81" cStringUsingEncoding:NSUTF8StringEncoding];
NSString *decode_string = [NSString stringWithUTF8String:ch];
NSLog(@"%@",decode_string);
Output: Hii
Swift
我可以在 SWift
中将 \xF0\x9F\x98\x81
转换为 </code>。
首先,我将 hexa 字符串转换为 <code>Data
,然后使用 UTF-8
编码转换回 String
。
var str = "\xF0\x9F\x98\x81"
if let data = data(fromHexaStr: str) {
print(String(data: data, encoding: String.Encoding.utf8) ?? "")
}
Output:
下面是我用来将十六进制字符串转换为数据的函数。我关注了 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())
Hi 81
hexaStr = "Welcome to SP19!\xF0\x9f\x98\x81"
print(hexaStr.hexaDecoededString())
Welcome to SP19!
我解决了你的问题,但它需要更多的工作才能使其通用,这里的问题是你的 Emijo 由 Hex Byte
x9F
表示,所以我们必须将此 Hex 转换为 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
}
当 WS API 将表情符号作为字符串发送时,我收到以下字符串作为响应:
let strTemp = "Hii \xF0\x9F\x98\x81"
我想把它转换成这样的表情图标 -> Hii
我认为它以 UTF-8 格式出现,如下图所示:Image Unicode
I have tried decoding it Online using UTF-8 Decoder
表情成功解码
解码前:
解码后:
但这里的问题是我不知道如何在 Swift 中使用它。
我参考了 link 但它对我不起作用。
Swift Encode/decode emojis
如有任何帮助,我们将不胜感激。
谢谢。
正如您已经提供的 link 转换器工具,它显然在进行 UTF-8
编码和解码。您有 UTF-8
编码的字符串,所以这里是 UTF8-Decoding
.
Objective-C
const char *ch = [@"Hii \xF0\x9F\x98\x81" cStringUsingEncoding:NSUTF8StringEncoding];
NSString *decode_string = [NSString stringWithUTF8String:ch];
NSLog(@"%@",decode_string);
Output: Hii
Swift
我可以在 SWift
中将 \xF0\x9F\x98\x81
转换为 </code>。
首先,我将 hexa 字符串转换为 <code>Data
,然后使用 UTF-8
编码转换回 String
。
var str = "\xF0\x9F\x98\x81"
if let data = data(fromHexaStr: str) {
print(String(data: data, encoding: String.Encoding.utf8) ?? "")
}
Output:
下面是我用来将十六进制字符串转换为数据的函数。我关注了 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())
Hi 81
hexaStr = "Welcome to SP19!\xF0\x9f\x98\x81"
print(hexaStr.hexaDecoededString())
Welcome to SP19!
我解决了你的问题,但它需要更多的工作才能使其通用,这里的问题是你的 Emijo 由 Hex Byte
x9F
表示,所以我们必须将此 Hex 转换为 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
}