在Swift中将数字转换为给定字符串中的字符串

时间:2018-08-16 01:42:54

标签: swift string

我给了一个像4eysg22yl3kk这样的字符串,我的输出应该是这样的: foureysgtweny-twoylthreekk或者,如果给我0123,它应该输出为123。因此,基本上,当我扫描字符串时,我需要将数字转换为字符串。 当我遍历字符串时,我不知道如何在Swift中实现它?任何想法?

2 个答案:

答案 0 :(得分:0)

您实际上有两个基本问题。

第一个是将“数字”转换为“拼出”值(即,将1转换为one)。实际上,这很容易解决,因为NumberFormatter具有spellOut样式属性

let formatter = NumberFormatter()
formatter.numberStyle = .spellOut
let text = formatter.string(from: NSNumber(value: 1))

这将使"one"整齐。

不过,另一个问题是如何将数字与文本分开?

虽然我可以从混合的String中找到许多用于“提取”数字或字符的解决方案,但我找不到一个能同时返回两者并在边界上划分的解决方案,因此,根据您的输入,我们最终以["4", "eysg", "22", "yl", "3", "kk"]结束。

那么,该扮演我们自己的角色了...

func breakApart(_ text: String, withPattern pattern: String) throws -> [String]? {
    do {
        let regex = try NSRegularExpression(pattern: "[0-9]+", options: .caseInsensitive)
        var previousRange: Range<String.Index>? = nil
        var parts: [String] = []
        for match in regex.matches(in: text, options: [], range: NSRange(location: 0, length: text.count)) {
            guard let range = Range(match.range, in: text) else {
                return nil
            }
            let part = text[range]
            if let previousRange = previousRange {
                let textRange = Range<String.Index>(uncheckedBounds: (lower: previousRange.upperBound, upper: range.lowerBound))
                parts.append(String(text[textRange]))
            }
            parts.append(String(part))
            previousRange = range
        }
        if let range = previousRange, range.upperBound != text.endIndex {
            let textRange = Range<String.Index>(uncheckedBounds: (lower: range.upperBound, upper: text.endIndex))
            parts.append(String(text[textRange]))
        }
        return parts
    } catch {
    }
    return nil
}

好的,所以这有点“肮脏”(恕我直言),但我似乎想不出更好的方法,希望有人会很友好地为您提供一些提示;)

基本上,它的工作是使用正则表达式查找所有数字组,然后构建一个数组,将字符串在匹配的边界周围切开-就像我说的那样,它很粗糙,但是可以完成工作。 / p>

从那里开始,我们只需要映射结果,并在搜索过程中阐明数字...

let formatter = NumberFormatter()
formatter.numberStyle = .spellOut
let value = "4eysg22yl3kk"
if let parts = try breakApart(value, withPattern: pattern) {
    let result = parts.map { (part) -> String in
        if let number = Int(part), let text = formatter.string(from: NSNumber(value: number)) {
            return text
        }
        return part
        }.joined(separator: " ")
    print(result)
}

这将最终打印出four eysg twenty-two yl three kk,如果您不想使用空格,只需在separator函数中删除join

我是在Playgrounds中完成的,因此可能需要清理

答案 1 :(得分:0)

除了将String转换为数组并逐字符检查char之外,我无需解决任何其他问题就能解决我的问题。如果找到一个数字,则将其保存在临时字符串中,一旦发现下一个字符不是数字,便将其转换为文本。

let inputString = Array(string.lowercased())