1

Is there a quick way to validate if an NSString is formatted as US currency?

So what I am looking to confirm is that character 0 is a $, the following characters are numeric except for string.length-3 which could be a decimal (showing the change is optional).

So this passes $1000.00 and this passes $1000 but this would fail $1000B.

Thanks

PruitIgoe
  • 6,166
  • 16
  • 70
  • 137
  • http://stackoverflow.com/questions/2369666/how-to-use-nsnumberformatter-for-currency-to-print-in-uitextfield – iPatel Apr 10 '13 at 14:05
  • you didn't say what you're using this in (a user-editable text field, a static label or?), but in general any answer is likely to make use of NSNumberFormatter – Michael Dautermann Apr 10 '13 at 14:06
  • `^\$\d+(?:\.\d{2})?$` – Joe Apr 10 '13 at 14:06
  • http://stackoverflow.com/questions/1960300/converting-nsstring-to-currency-the-complete-story – iPatel Apr 10 '13 at 14:06
  • @iPatel, if any of these related questions are duplicate of this one, you should vote to close this one as a duplicate – Michael Dautermann Apr 10 '13 at 14:07
  • Do you also have the number, or just the formatted string? – Marcus Adams Apr 10 '13 at 14:07
  • @Michael - It's coming from a UITextField, I am checking it in the textFieldDidEndEditing protocol method...@Marcus - just the formatted string - it's coming from a textfield but the entry could be $1000.00 or 1000 or 1000;C, I want to accept 1 or 2 but not 3. – PruitIgoe Apr 10 '13 at 14:10

2 Answers2

9

One simple way would be to validate the string using this regular expression:

^[$][0-9]+([.][0-9]{2})?$
^ ^   ^  ^  ^   ^   ^  ^^
| |   |  |  |   |   |  ||
| |   |  |  |   |   |  |+-- End-of-input marker 
| |   |  |  |   |   |  +--- Optional
| |   |  |  |   |   +------ Repeated exactly two times
| |   |  |  |   +---------- A decimal digit
| |   |  |  +-------------- A dot (literal)
| |   |  +----------------- Repeated once or more
| |   +-------------------- A decimal digit
| +------------------------ The dollar sign (literal)
+-------------------------- Start-of-input marker

Here is a sample code that uses the above expression:

NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression
    regularExpressionWithPattern:@"^[$][0-9]+([.][0-9]{2})?$"
                         options:NSRegularExpressionCaseInsensitive
                           error:&error];
if ([regex numberOfMatchesInString:@"$321.05" options:0 range:NSMakeRange(0, 7)]) {
    NSLog(@"Success");
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • So in your example changing this NSMakeRange(0, string.length) would make it dynamic, right? – PruitIgoe Apr 10 '13 at 14:29
  • Works in the US. Is there a way generate the regex based on the locale? To match the user's request, I think you'd want a `?` after the `$` also to make it optional. Also, needs to be extended for commas. – Marcus Adams Apr 10 '13 at 14:29
  • @PruitIgoe That is correct. I hard-coded `7` because I also hard-coded `@"$321.00"`, but in general you need to supply the correct length. – Sergey Kalinichenko Apr 10 '13 at 14:31
  • @MarcusAdams That's by design: the OP asked about US dollars. Using the `NSNumberFormatterCurrencyStyle` solution will accept `£12.34` in England and `12.34€` in Germany, which may or may not be desirable. – Sergey Kalinichenko Apr 10 '13 at 14:34
  • Great and very complete answer!! – VansFannel May 07 '13 at 10:01
3

NSNumberFormatter not only has stringFromNumber, but it also has numberFromString.

NSString *string = @"$1,000.00";
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle: NSNumberFormatterCurrencyStyle];
NSNumber *number = [numberFormatter numberFromString:string];
if (number) {
   // Success
}
Marcus Adams
  • 53,009
  • 9
  • 91
  • 143