6

Is there a better or shorter way of striping out all the non-digit characters with Objective-C on the iPhone?

NSString * formattedNumber = @"(123) 555-1234";
NSCharacterSet * nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];

NSString * digits;
NSArray * parts = [formattedNumber componentsSeparatedByCharactersInSet:nonDigits];
if ( [parts count] > 1 ) {
    digits = [parts componentsJoinedByString:@""];
} else {
    digits = [parts objectAtIndex:0];
}
return digits;
Mack
  • 109
  • 3
  • 1
    Be aware that non-digits such as '+' are valid in phone numbers. – Dirk Vollmar Sep 27 '10 at 21:53
  • Phone numbers should only *start* with a +, according to [ITU-T E.123](http://www.itu.int/rec/T-REC-E.123-200102-I/en). – dreamlax Sep 27 '10 at 22:09
  • That is true, but I need to get the number into an Integer type. I should have included that in the question detail. – Mack Sep 27 '10 at 23:33
  • 1
    Mack: Don't do that. Phone numbers can be larger than can fit into any of the integral types, especially when you include dialing codes, country codes, extensions, etc.; moreover, as dreamlax already told you, there are at least two (I would say three, the third being the comma) non-numeric characters that you *must not* strip. You will corrupt user input if you try to stuff the phone number into an integral type. – Peter Hosey Sep 28 '10 at 07:37
  • possible duplicate of [Remove all but numbers from NSString](http://stackoverflow.com/questions/1129521/remove-all-but-numbers-from-nsstring) – jscs May 17 '11 at 01:12

4 Answers4

4

You could use a RegEx-replacement that replaces [\D] with nothing.

kba
  • 19,333
  • 5
  • 62
  • 89
3

Dupe of Remove all but numbers from NSString

The accepted answer there involves using NSScanner, which seems heavy-handed for such a simple task. I'd stick with what you have there (though someone in the other thread suggested a more compact version if it, thus:

NSString *digits = [[formattedNumber componentsSeparatedByCharactersInSet:
                        [[NSCharacterSet decimalDigitCharacterSet] invertedSet]] 
                       componentsJoinedByString:@""];
Community
  • 1
  • 1
zpasternack
  • 17,838
  • 2
  • 63
  • 81
3

Phone numbers can contain asterisks and number signs (* and #), and may start with a +. The ITU-T E-123 Recommandation recommends that the + symbol be used to indicate that the number is an international number and also to serve as a reminder that the country-specific international dialling sequence must be used in place of it.

Spaces, hyphens and parentheses cannot be dialled so they do not have any significance in a phone number. In order to strip out all useless symbols, you should remove all characters not in the decimal character set, except * and #, and also any + not found at the start of the phone number.

To my knowledge, there is no standardised or recommended way to represent manual extensions (some use x, some use ext, some use E). Although, I have not encountered a manual extension in a long time.

NSUInteger inLength, outLength, i;
NSString *formatted = @"(123) 555-5555";

inLength = [formatted length];
unichar result[inLength];

for (i = 0, outLength = 0; i < inLength; i++)
{
    unichar thisChar = [formatted characterAtIndex:i];

    if (iswdigit(thisChar) || thisChar == '*' || thisChar == '#')
        result[outLength++] = thisChar;   // diallable number or symbol
    else if (i == 0 && thisChar == '+')
        result[outLength++] = thisChar;   // international prefix
}

NSString *stripped = [NSString stringWithCharacters:result length:outLength];
dreamlax
  • 93,976
  • 29
  • 161
  • 209
0

You could do something like this:

NSString *digits = [[formattedNumber componentsSeparatedByCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]] componentsJoinedByString:@""];

Noting 0xA3's comment above, you could optionally use a different NSCharacterSet that includes + and other non-digits that are valid in phone numbers.

Greg
  • 33,450
  • 15
  • 93
  • 100