首页 > 解决方案 > 将 Swift 字符串编码为转义的 unicode?

问题描述

API 数据字段仅支持 ASCII 编码——但我需要支持 Unicode(表情符号、外来字符等)

我想将用户的文本输入编码为转义的 unicode 字符串:

let textContainingUnicode = """
Let's go  in the .
  And some new lines.
"""

let result = textContainingUnicode.unicodeScalars.map { $0.escaped(asASCII: true)}
  .joined(separator: "")
  .replacingOccurrences(
    of: "\\\\u\\{(.+?(?=\\}))\\}", <- converting swift format \\u{****}
    with: "\\\\U$1",               <- into format python expects
    options: .regularExpression)

result这是"Let\'s go \U0001F3CA in the \U0001F30A.\n And some new lines."

并在服务器上使用 python 解码:

codecs.decode("Let\\'s go \\U0001F3CA in the \\U0001F30A.\\n And some new lines.\n", 'unicode_escape')

但这闻起来很有趣——我真的需要快速进行如此多的字符串操作来获得转义的 unicode 吗?这些格式是否没有跨语言标准化。

标签: swiftunicode

解决方案


您可以在集合中使用 reduce 并检查每个字符是否为 ASCII,如果为 true,则返回该字符,否则将特殊字符转换为 unicode:

斯威夫特 5.1 • Xcode 11

extension Unicode.Scalar {
    var hexa: String { .init(value, radix: 16, uppercase: true) }
}

extension Character {
    var hexaValues: [String] {
        unicodeScalars
            .map(\.hexa)
            .map { #"\\U"# + repeatElement("0", count: 8-$0.count) + $0 }
    }
}

extension StringProtocol where Self: RangeReplaceableCollection {
    var asciiRepresentation: String { map { $0.isASCII ? .init($0) : $0.hexaValues.joined() }.joined() }
}

let textContainingUnicode = """
Let's go  in the .
  And some new lines.
"""

let asciiRepresentation = textContainingUnicode.asciiRepresentation
print(asciiRepresentation)  // "Let's go \\U0001F3CA in the \\U0001F30A.\n  And some new lines."

推荐阅读