将字符串转换为货币数字格式,有、没有或有 0 个小数位

Convert string into currency number format, with, without or with 0 decimal places

我有一个字符串,它总是转换成类似 this 的字符串,其中用户输入一个数字并且总是从小数位开始,

所以我有 0.01 -> 0.10 -> 1.00

但我不想要那样的东西,我只想转换用户输入的内容

这是我将 100000 转换为 1,000.00 的现有代码

func convertme(string: String) -> String{
    var number: NSNumber!
    let formatter = NumberFormatter()
    formatter.numberStyle = .currencyAccounting
    formatter.currencySymbol = ""
    formatter.maximumFractionDigits = 2
    formatter.minimumFractionDigits = 2

    var amountWithPrefix = string

    // remove from String: "$", ".", ","
    let regex = try! NSRegularExpression(pattern: "[^0-9]", options: .caseInsensitive)
    amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, string.count), withTemplate: "")
    
    print("amountWithPrefix", amountWithPrefix)

    let double = (amountWithPrefix as NSString).doubleValue
    number = NSNumber(value: (double / 100))

    // if first number is 0 or all numbers were deleted
    guard number != 0 as NSNumber else {
        return ""
    }

    return formatter.string(from: number)!
}

预期结果:

我想在不添加额外数据的情况下格式化字符串上的数字,我想将 (100000. 变成 100,000.) (100000.0 变成 100,000.0

我想把我的100000换算成100000,只有用户输入小数的时候才会有小数,所以当用户输入100000.00的时候会换算成100000.00。

PS。我有一个只接受数字而不接受小数的正则表达式,我怎样才能让它也接受小数?

您可以简单地从原始字符串中过滤掉非数字或句点,尝试将结果字符串强制转换为整数。如果成功将格式化程序最大小数位数设置为零,否则将最大小数位数设置为 2 并将字符串强制为双倍:

extension Formatter {
    static let currency: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.locale = .init(identifier: "en_US_POSIX")
        formatter.numberStyle = .currencyAccounting
        formatter.currencySymbol = ""
        return formatter
    }()
}

extension Numeric {
    var currencyUS: String {
         Formatter.currency.string(for: self) ?? ""
    }
}

func convertme(string: String) -> String {
    let string = string.filter("0123456789.".contains)
    if let integer = Int(string)  {
        Formatter.currency.maximumFractionDigits = 0
        return Formatter.currency.string(for: integer) ?? "0"
    }
    Formatter.currency.maximumFractionDigits = 2
    return Double(string)?.currencyUS ?? "0"
}

convertme(string: "100000")     // "100,000"
convertme(string: "100000.00")  // "100,000.00"


edit/update: “十万。”它不是有效的数字格式。您需要在字符串末尾手动插入句号。

func convertme(string: String) -> String {
    var string = string.filter("0123456789.".contains)
    // this makes sure there is only one period and keep only the last one in the string
    while let firstIndex = string.firstIndex(of: "."),
          let _ = string[firstIndex...].dropFirst().firstIndex(of: ".") {
        string.remove(at: firstIndex)
    }
    // get the index of the period in your string
    if let index = string.firstIndex(of: ".") {
        // get the fraction digits count and set the number formatter appropriately
        let fractionDigits = string[index...].dropFirst().count
        Formatter.currency.minimumFractionDigits = fractionDigits
        Formatter.currency.maximumFractionDigits = fractionDigits
        // Number Formatter wont add a period at the end of the string if there is no fractional digits then you need to manually add it yourself
        if fractionDigits == 0 {
            return (Double(string)?.currencyUS ?? "0") + "."
        }
    } else {
        // in case there is no period set the fraction digits to zero
        Formatter.currency.minimumFractionDigits = 0
        Formatter.currency.maximumFractionDigits = 0
    }
    return Double(string)?.currencyUS ?? "0"
}

游乐场测试:

convertme(string: "100000")      // "100,000"
convertme(string: "100000.")     // "100,000."
convertme(string: "100000.0")    // "100,000.0"
convertme(string: "100000.00")   // "100,000.00"
convertme(string: "100000.000")  // "100,000.000"