Ios 带有NumberFormatter和货币字符串的欧元错误

Ios 带有NumberFormatter和货币字符串的欧元错误,ios,swift,swift3,nsdecimalnumber,currency-formatting,Ios,Swift,Swift3,Nsdecimalnumber,Currency Formatting,我在Swift字符串扩展中编写了一个函数,用于获取任何货币字符串,例如$500.00或250,75欧元,甚至500,然后从中返回一个nsdecimalnumber 不幸的是,当我传入250,75欧元时,它会命中代码的if nf.numberfrom:self==nil部分,并计算为nil,因此不会返回任何结果。只有在添加带有逗号的更改时才会出现这种情况,例如250,75。但是,如果我做了250次,它就行了。这似乎只是为了欧元。美元工程罚款500.00美元、125.75美元等 这是我的密码。有什么

我在Swift字符串扩展中编写了一个函数,用于获取任何货币字符串,例如$500.00或250,75欧元,甚至500,然后从中返回一个nsdecimalnumber

不幸的是,当我传入250,75欧元时,它会命中代码的if nf.numberfrom:self==nil部分,并计算为nil,因此不会返回任何结果。只有在添加带有逗号的更改时才会出现这种情况,例如250,75。但是,如果我做了250次,它就行了。这似乎只是为了欧元。美元工程罚款500.00美元、125.75美元等

这是我的密码。有什么想法吗?谢谢你抽出时间

extension String{
func toDecimalFromCurrencyString() -> NSDecimalNumber
    {

        let nf = NumberFormatter()
        nf.numberStyle = NumberFormatter.Style.currency
        nf.formatterBehavior = NumberFormatter.Behavior.behavior10_4
        nf.generatesDecimalNumbers = true

        var test = self.replacingOccurrences(of: nf.currencySymbol!, with: "", options: NSString.CompareOptions.literal, range: nil)
        test = test.replacingOccurrences(of: nf.currencyDecimalSeparator!, with: "", options: NSString.CompareOptions.literal, range: nil)
        test = test.replacingOccurrences(of: nf.currencyGroupingSeparator!, with: "", options: NSString.CompareOptions.literal, range: nil)
        let scanner: Scanner = Scanner(string:test)
        let isNumeric = (scanner.scanDecimal(nil) && scanner.isAtEnd)

        //If the string entered isn't numeric (for example ... or $$$, then fail)
        if (self.trimmingCharacters(in: CharacterSet.whitespaces).utf16.count == 0 || (!isNumeric))
        {
            return 0.0
        }
        //If the string contains more than one decimal separator (.), or more than one currency symbol ($), return 0.0
        else if ((self.components(separatedBy: nf.currencyDecimalSeparator!).count-1) > 1 || (self.components(separatedBy: nf.currencySymbol!).count - 1) > 1) {
            return 0.0
        }
        //If the string contains more than one consecutive currency grouping separator (i.e. ,,) then return 0.0
        else if ((components(separatedBy: nf.currencyGroupingSeparator! + nf.currencyGroupingSeparator!).count-1) > 0)
        {
            return 0.0
        }
        else
        {
            if (nf.number(from: self) == nil) {
                return 0.00
            }
            else {
                return nf.number(from: self) as! NSDecimalNumber
            }
        }
    }


}

您可以简单地从字符串中修剪所有非数字,并使用两个数字格式化程序,一个带点,另一个带逗号,并在链中使用nil合并运算符,如下所示:

extension Formatter {
    static let decimalWithDotSeparator: NumberFormatter = {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.decimalSeparator = "."
        return numberFormatter
    }()
    static let decimalWithCommaSeparator: NumberFormatter = {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.decimalSeparator = ","
        return numberFormatter
    }()
}

extension String {
    var numberFromCurrency: NSDecimalNumber? {
        var string = self
        while let first = string.characters.first, Int("\(first)") == nil {
            string = String(string.characters.dropFirst())
        }
        while let last = string.characters.last, Int("\(last)") == nil {
            string = String(string.characters.dropLast())
        }
        return (Formatter.decimalWithDotSeparator.number(from: string) ??
                Formatter.decimalWithCommaSeparator.number(from: string) ?? 0)
                .decimalValue.decimalNumber
    }
}

extension Decimal {
    var decimalNumber: NSDecimalNumber { return NSDecimalNumber(decimal: self) }
}

我不相信250,75是一个有效的格式。它应该是250.75decimal而不是逗号,或者在右边是25075逗号place@Malik有些地区使用,而不是。分隔数字的整数部分和小数部分。您可能希望使用currencyCode而不是locale@NullHypothesis你试过我下面的建议了吗?嘿,利奥-还没有-今晚要试试这个!感谢您抽出时间回复。会让你知道的!它起作用了!非常感谢你,利奥。感谢您抽出时间来帮助我:
let dollar = "$249.99"
dollar.numberFromCurrency   // 249.99

let real = "R$249,99"
real.numberFromCurrency   // 249.99

let euro = "0,50€"
euro.numberFromCurrency    // 0.5