swift 如何将Unicode Scalar转换为CGFloat

9rygscc1  于 2023-09-29  发布在  Swift
关注(0)|答案(1)|浏览(92)

我有一个可以包含任意值的字符串;例如,它可以是“1”、“1/2 ",或者它可以是“一”。
如果它是一个数字,我想把它转换成一个浮点数。如果它只是“1”,这很简单

if let newFloat = NumberFormatter().number(from: string) {
    let float = CGFloat(truncating: newFloat)
    print(float)
}

但如果是“½”,则代码失败。
我对String做了一个扩展,它可以找到“粗俗的分数”并将其替换为小数。它是有效的,但1。感觉很粗糙,2。它不考虑部分分数,这意味着字符串“1”输出为“10.333”。我已经将其粘贴在下面-有更好的方法吗?

extension String {
    func replaceVulgarFractions() -> String {
        var modifiedText = self
        
        let vulgarFractionRegex = "[½⅓⅔¼¾⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞]"
        
        while let matchRange = modifiedText.range(of: vulgarFractionRegex, options: .regularExpression) {
            let matchedFraction = String(modifiedText[matchRange])
            if let decimalValue = matchedFraction.vulgarFractionToDecimal() {
                modifiedText = modifiedText.replacingCharacters(in: matchRange, with: String(format: "%.3f", decimalValue))
            }
        }
        
        return modifiedText
    }
    
    func vulgarFractionToDecimal() -> Double? {
        switch self {
        case "½": return 0.5
        case "⅓": return 1.0 / 3.0
        case "⅔": return 2.0 / 3.0
        case "¼": return 0.25
        case "¾": return 0.75
        case "⅕": return 0.2
        case "⅖": return 0.4
        case "⅗": return 0.6
        case "⅘": return 0.8
        case "⅙": return 1.0 / 6.0
        case "⅚": return 5.0 / 6.0
        case "⅐": return 1.0 / 7.0
        case "⅛": return 1.0 / 8.0
        case "⅜": return 3.0 / 8.0
        case "⅝": return 5.0 / 8.0
        case "⅞": return 7.0 / 8.0
        default: return nil
        }
    }
}
gwbalxhn

gwbalxhn1#

我没有看到任何内置的方法来翻译粗俗的分数字符小数。一种解决方案是修复代码,以调整字符串格式中的前导0
使用以下代码更新while循环:

while let matchRange = modifiedText.range(of: vulgarFractionRegex, options: .regularExpression) {
    let matchedFraction = String(modifiedText[matchRange])
    if let decimalValue = matchedFraction.vulgarFractionToDecimal() {
        var fracStr = String(format: "%3.3f", decimalValue) // Your original format
        // Remove the leading zero unless this is the first character
        if fracStr.hasPrefix("0.") && matchRange.lowerBound != modifiedText.startIndex {
            fracStr = String(fracStr.dropFirst())
        }
        modifiedText = modifiedText.replacingCharacters(in: matchRange, with: fracStr)
    }
}

此代码从字符串格式的结果中删除任何前导零,除非这是来自原始字符串的第一个字符。
这些更改将给予“1½”提供“1.5”,为“½”提供“0.5”。

相关问题