Как вы уже дали ссылку на инструмент конвертера, который явно выполняет кодирование и декодирование 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);
Вывод: Hii ?
Swift
Я могу конвертировать \\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) ?? "")
}
Вывод: ?
Ниже приведена функция, которую я использовал для преобразования шестнадцатеричной строки в данные.Я следовал этому ответу .
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}
regex, потому что он также сканирует 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, в котором я проверяю каждые 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())
Добро пожаловать в SP19! ?