iOS:删除nsdecimalnumber中的千分隔板进行编辑



我在数据库中存储的十进制数字为十进制。我根据用户的语言环境显示它们:

- (NSString *) getLocalizedCurrencyStringWithDigits
{
    NSNumberFormatter *numberFormatter =[[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [numberFormatter setLocale:[NSLocale currentLocale]];
    [numberFormatter setMinimumFractionDigits:2];
    [numberFormatter setMaximumFractionDigits:2];
    NSString *numberString = [numberFormatter stringFromNumber:self];
    return numberString;
}

我在Textfields中显示这些字符串,这些字符品可编辑。因此,如果用户开始编辑该字段,我想删除千分离器。否则(在我的国家)我输入1'000.55,然后它不识别"'"并仅保存一个1。这是我的功能来解析文本字段,在视图控制器中,此确切的返回值将保存到数据库:

+ (NSDecimalNumber *) getUnLocalizedDecimalNumberWithString:(NSString *)currencyString
{
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [numberFormatter setLocale:[NSLocale currentLocale]];
    [numberFormatter setMinimumFractionDigits:2];
    [numberFormatter setMaximumFractionDigits:2];
    BOOL isDecimal = [numberFormatter numberFromString:currencyString] != nil;
    if(isDecimal){
        return [NSDecimalNumber decimalNumberWithString:currencyString locale:[NSLocale currentLocale]];
    } else {
        return [NSDecimalNumber zero];
    }

但是,我不工作...实际上,如果使用"'"的数字和没有正确保存的数字,那将是最好的:/

编辑(我的解决方案):让它像这样工作:

- (NSString *) getLocalizedCurrencyStringWithDigits:(int)digits
{
    NSNumberFormatter *numberFormatter =[[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [numberFormatter setLocale:[NSLocale currentLocale]];
    [numberFormatter setMinimumFractionDigits:digits];
    [numberFormatter setMaximumFractionDigits:digits];
    NSString *numberString = [numberFormatter stringFromNumber:self];
    return numberString;
}
+ (NSDecimalNumber *) getUnLocalizedDecimalNumberWithString:(NSString *)currencyString
{
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [numberFormatter setLocale:[NSLocale currentLocale]];
    [numberFormatter setMinimumFractionDigits:2];
    [numberFormatter setMaximumFractionDigits:2];
    NSNumber *formatedCurrency = [numberFormatter numberFromString:currencyString];
    BOOL isDecimal = formatedCurrency != nil;
    if(isDecimal){
        return [NSDecimalNumber decimalNumberWithDecimal:[formatedCurrency decimalValue]];
    } else {
        return [NSDecimalNumber zero];
    }
}

(nsdecimalnumber *)getunlocalizeddecimalnumberwithstring :( nsstring *)currencystring

现在正确解释每个字符串。1'000和1000和1000.00现在都是1000: - )

我认为最简单,最干净的解决方案是:

NSLocale *locale = [NSLocale currentLocale];
NSString *thousandSeparator = [locale objectForKey:NSLocaleGroupingSeparator];
NSString *result = [decimalStringWithThousandSeperator stringByReplacingOccurrencesOfString:thousandSeparator withString:@""];

在您的NSNumberFormatter实例上将usesGroupingSeparator设置为NO(或Swift中的false)。

它在删除其余分组分隔器时保持小数分离器。

我看到您的代码有几个问题,也不清楚您要做什么。

第一个问题是,在您的方法中,getLocalizedCurrencyStringWithDigits,您正在调用stringfromnumber并传递" self"。这是没有意义的,除非您创建了NSnumber的自定义子类,我怀疑您是否正在这样做。

下一个问题是您正在使用NSDecimalnumber类,我怀疑这不是您认为的。这是一个特殊的NSNUMBER子类,旨在进行10次数学基础数学,而无需使用二进制算术在分数数字上进行数学的舍入错误。NSDECIMALNUMBER是一个非常专业的课程,除非您确切地知道为什么要使用它,否则不是您需要的。只需使用常规的nsnumber即可。

然后是下一个问题。您说您正在尝试"删除成千上万的分离器"。几千个分离器?如果将一个数值转换为字符串,则应为用户的语言环境以正确的格式。另外,如果要显示的是货币金额,为什么要使用nsnumberformatterDecimalstyle?您不应该使用nsnumberformatterCurrencyStyle吗?

从此答案中,删除所有不是数字或十进制的字符,使用NSNumberFormatterfloatValue

转换时,您应该仅获得一个有效数字的剥离字符串
NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet 
        characterSetWithCharactersInString:@".0123456789"];
while ([scanner isAtEnd] == NO) {
  NSString *buffer;
  if ([scanner scanCharactersFromSet:currencyString intoString:&buffer]) {
    [strippedString appendString:buffer];
  } else {
    [scanner setScanLocation:([scanner scanLocation] + 1)];
  }
}

,或者您可以使用正则表达式:

NSString * strippedNumber = [currencyString stringByReplacingOccurrencesOfRegex:@"^([0-9]+)?(\.([0-9]{1,2})?)?$" withString:@""];

我不能发誓,如果从这里开始,我偷了此处使用的正则语法。我在那里没有太多经验。

这是Swift 5版本

var numberStr = "1,000"
let thousandsSep = Locale.current.groupingSeparator
numberStr = numberStr.replacingOccurrences(of: thousandsSep!, with: "")
let numberDouble = Double(numberStr)

最新更新