Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone: How to get number from string with currency symbol in Objective-C

I am trying to get number(float value) from string with currency symbol.

eg. from "¥1,234" to 1234 from "AU$3,456" to 3456 from "56.78€" to 56.78

I tried the following code but I got 0 as a result.

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setLenient:YES];
NSNumber *number = [formatter numberFromString:text];
NSDecimalNumber *money = [NSDecimalNumber decimalNumberWithDecimal:[number decimalValue]];
float fval = [money floatValue];

Thanks in advance!

like image 875
tmrex7 Avatar asked Dec 22 '12 03:12

tmrex7


2 Answers


The difficulty here is that the currency decimal separators are different for different countries. To make matters worse, the digit grouping symbols used in some regions are used as decimal separators in others. See:

http://en.wikipedia.org/wiki/Decimal_mark#Hindu.E2.80.93Arabic_numeral_system

http://en.wikipedia.org/wiki/Decimalisation#Decimal_currency

Therefore, the naïve approach, of relying on the symbol for the decimal separators, or alternatively using the number of decimals places after a suspected decimal marker may not be 100% accurate. If you have a particular subset you're dealing with, by all means use some sort of heuristic.

Given a global problem space, however, I think the best thing to do would be to use the locale if you had it:

NSString* text =  @"$3,456.78 USD";
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
text = [text stringByReplacingOccurrencesOfString:formatter.internationalCurrencySymbol withString:@""];
float fval = [formatter numberFromString:text].floatValue;
like image 134
markshiz Avatar answered Nov 09 '22 10:11

markshiz


I'm sure there are more efficient ways, but you can:

NSArray *strings = @[@"¥1,234",@"AU$3,456.78",@"56.78€"];

NSCharacterSet *nonNumbersSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet];

for (NSString *string in strings)
{
    NSString *result = [string stringByTrimmingCharactersInSet:nonNumbersSet]; 
    result = [result stringByReplacingOccurrencesOfString:@"," withString:@""]; 
    CGFloat floatResult = [result floatValue];
    NSLog(@"%@ -> %.2f", result, floatResult);
}

or, you can use a scanner:

NSArray *strings = @[@"¥1,234",@"AU$3,456.78",@"56.78€"];
NSCharacterSet *numbersSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789.,"];

for (NSString *string in strings)
{
    NSString *result;
    NSScanner *scanner = [NSScanner scannerWithString:string];
    [scanner scanUpToCharactersFromSet:numbersSet intoString:nil];
    [scanner scanCharactersFromSet:numbersSet intoString:&result];
    result = [result stringByReplacingOccurrencesOfString:@"," withString:@""];
    CGFloat floatResult = [result floatValue];
    NSLog(@"%@ -> %.2f", result, floatResult);
}

These, of course, assume that numbers are using commas as the thousands separator.

You can also use a NSNumberFormatter:

NSArray *strings = @[@"¥1,234",@"AU$3,456.78",@"56.78€"];
NSCharacterSet *nonNumbersSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789.,"] invertedSet];

for (NSString *string in strings)
{
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    formatter.numberStyle = NSNumberFormatterDecimalStyle;
    NSString *result = [string stringByTrimmingCharactersInSet:nonNumbersSet];
    NSNumber *numberResult = [formatter numberFromString:result];
    NSLog(@"%@ -> %.2f", result, [numberResult floatValue]);
}
like image 26
Rob Avatar answered Nov 09 '22 10:11

Rob