设备对字符串进行编码""为"\uD83E\uDD1B\uD83C\uDFFD"
。此字符串中表示的十六进制数字来自字符的UTF-16十六进制编码。 Unicode代码点U+1F91B, U+1F3FD
从UTF-32十六进制编码中获取其编号。
稍后再说一下,在Swift中,我们可以像这样做一个文字" \ u {1F91B} \ u {1F3FD}"我们将得到角色""正如所料。
"\uD83E\uDD1B\uD83C\uDFFD"
转换为""?我尝试将字符串转换为[UInt32]
32位整数数组,然后使用它来创建unicode标量,但这仅适用于可以在单个UTF中表示的Unicode字符-32代码点。
以下是我使用的源代码。
extension String {
func decodeBlock() -> String {
let strings = self.components(separatedBy: "\\u")
var scalars : [UInt32] = []
var value: UInt32 = 0
for string in strings {
print(string)
let scanner = Scanner(string: string)
if scanner.scanHexInt32(&value) {
scalars.append(value)
}
}
let utf32chars = scalars
var str = ""
var generator = utf32chars.makeIterator()
var utf32 : UTF32 = UTF32()
var done = false
while !done {
let r = utf32.decode(&generator)
switch (r) {
case . emptyInput:
done = true
case .scalarValue(let val):
str.append(Character(val))
case .error:
return "$"
}
}
return str
return self
}
}
它是从代码中改编而来回答类似问题的。 https://stackoverflow.com/a/41412056/731773
编码字符串的来源是org.apache.commons.lang.StringEscapeUtils escapeJava
函数,可以找到here。
答案 0 :(得分:0)
这有点像作弊,但UTF-16恰好是NSString
使用的编码,所以你可以借用NSString
的方法来实现它:
extension String {
func decodeBlock() -> String? {
var chars = [unichar]()
for substr in self.components(separatedBy: "\\u") where !substr.isEmpty {
if let value = UInt16(substr, radix: 16) {
chars.append(value)
} else {
return nil
}
}
return NSString(characters: chars, length: chars.count) as String
}
}
if let decoded = "\\uD83E\\uDD1B\\uD83C\\uDFFD".decodeBlock() {
print(decoded)
} else {
print("Cannot decode")
}
答案 1 :(得分:0)
这绝对是作弊,因为它只是在JavaScript中使用内置方法,但它可以工作。
func decode() -> String{
// getting a JSContext
let context = JSContext()
let encodedString = self
// defining a JavaScript function
let jsFunctionText = "var decode = function(encodedString) {\n" +
"var r = /\\\\u([\\d\\w]{4})/gi;\n" +
" x = encodedString\n" +
"x = x.replace(r, function (match, grp) {\n" +
" return String.fromCharCode(parseInt(grp, 16)); } );\n" +
" x = unescape(x);\n" +
" return x\n" +
"}"
// print(jsFunctionText)
context!.evaluateScript(jsFunctionText)!
// calling a JavaScript function
let jsFunction = context?.objectForKeyedSubscript("decode")
let decodedValue = jsFunction?.call(withArguments: [encodedString]);
if let decodedString = decodedValue?.toString() {
return decodedString
} else {
return self
}
}