如何在Swift中将字符串转换为unicode系列?

时间:2019-07-26 21:10:57

标签: swift unicode

我正在尝试在我的应用程序中创建一个功能,当用户在文本字段中键入内容时,文本将转换为unicode系列。

像下面一样,有一个用户键入的图像。在用户键入内容时,您会看到不同的unicode系列字符,当用户在单元格上键入内容时,您可以复制文本并将其粘贴到其他位置。

enter image description here

如果我想像上面的屏幕截图一样将文本变成黑气泡unicode系列,该怎么办?

1 个答案:

答案 0 :(得分:1)

您可以定义一个字符映射。这是一个让您入门的方法。

let circledMap: [Character : Character] = ["A": "?", "B": "?", "C": "?", "D": "?"] // The rest are left as an exercise 
let circledRes = String("abacab".uppercased().map { circledMap[$0] ?? $0 })
print(circledRes)

如果您的地图同时包含大写和小写字母的映射,则不要调用uppercased

创建所需的任何地图。使用每个macOS程序的“编辑”菜单上的“表情符号和符号”查看器花费大量时间。

let invertedMap: [Character : Character] = ["a": "ɐ", "b": "q", "c": "ɔ", "d": "p", "e": "ǝ", "f": "ɟ", "g": "ƃ", "h": "ɥ"]

在带圆圈的字母的情况下,最好定义一个范围,您可以将"A"..."Z"转换为"?"..."?"

这实际上需要比我预期更多的代码,但以下方法确实有效:

extension String {
    // A few sample ranges to get started
    // NOTE: Make sure each mapping pair has the same number of characters or bad things may happen
    static let circledLetters: [ClosedRange<UnicodeScalar> : ClosedRange<UnicodeScalar>] = ["A"..."Z" : "?"..."?", "a"..."z" : "?"..."?"]
    static let boxedLetters: [ClosedRange<UnicodeScalar> : ClosedRange<UnicodeScalar>] = ["A"..."Z" : "?"..."?", "a"..."z" : "?"..."?"]
    static let italicLetters: [ClosedRange<UnicodeScalar> : ClosedRange<UnicodeScalar>] = ["A"..."Z" : "?"..."?", "a"..."z" : "?"..."?"]

    func transformed(using mapping: [ClosedRange<UnicodeScalar> : ClosedRange<UnicodeScalar>]) -> String {
        let chars: [UnicodeScalar] = self.unicodeScalars.map { ch in
            for transform in mapping {
                // If the character is found in the range, convert it
                if let offset = transform.key.firstIndex(of: ch) {
                    // Convert the offset from key range into an Int
                    let dist = transform.key.distance(from: transform.key.startIndex, to: offset)
                    // Build new index into value range
                    let newIndex = transform.value.index(transform.value.startIndex, offsetBy: dist)
                    // Get the mapped character
                    let newch = transform.value[newIndex]
                    return newch
                }
            }

            // Not found in any of the mappings so return the original as-is
            return ch
        }

        // Convert the final [UnicodeScalar] into a new String
        var res = ""
        res.unicodeScalars.append(contentsOf: chars)

        return res
    }
}

print("This works".transformed(using: String.circledLetters)) // ???? ?????

上面的String扩展名也需要以下扩展名(感谢this answer):

extension UnicodeScalar: Strideable {
    public func distance(to other: UnicodeScalar) -> Int {
        return Int(other.value) - Int(self.value)
    }

    public func advanced(by n: Int) -> UnicodeScalar {
        let advancedValue = n + Int(self.value)
        guard let advancedScalar = UnicodeScalar(advancedValue) else {
            fatalError("\(String(advancedValue, radix: 16)) does not represent a valid unicode scalar value.")
        }
        return advancedScalar
    }
}
相关问题