18

I am trying to remove all of the non-numeric characters from an NSString, but I also need to keep the spaces. Here is what I have been using.

NSString *strippedBbox = [_bbox stringByReplacingOccurrencesOfString:@"[^0-9]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [_bbox length])];

If I give it a NSString of Test 333 9599 999 It will return 3339599999 but I need to keep the spaces in.

How can I do this?

jscs
  • 63,694
  • 13
  • 151
  • 195

7 Answers7

32

Easily done by creating a character set of characters you want to keep and using invertedSet to create an "all others" set. Then split the string into an array separated by any characters in this set and reassemble the string again. Sounds complicated but very simple to implement:

NSCharacterSet *setToRemove =   
    [NSCharacterSet characterSetWithCharactersInString:@"0123456789 "];
NSCharacterSet *setToKeep = [setToRemove invertedSet];

NSString *newString = 
        [[someString componentsSeparatedByCharactersInSet:setToKeep]
            componentsJoinedByString:@""];

result: 333 9599 99

memmons
  • 40,222
  • 21
  • 149
  • 183
  • This assumes English numeric characters; how easy to adjust would this be to be locale aware? – WDUK Feb 08 '14 at 23:47
  • 6
    Create a mutable copy of `[NSCharacterSet decimalDigitCharacterSet]` and add a space to it. – dreamlax Feb 08 '14 at 23:48
  • Updated with a cleaner, shorter version of the same code. – memmons Feb 08 '14 at 23:55
  • @dreamlax Slightly less code to just specify the digits in this case. If the set were alpha or alphanumeric, then using a mutable set would be preferable. – memmons Feb 08 '14 at 23:57
  • 1
    @MichaelG.Emmons: I was responding to WDUK's question, the `decimalDigitCharacterSet` includes decimal digit characters in other languages such as Indic and Arabic scripts too. – dreamlax Feb 09 '14 at 00:07
21

You could alter your first regex to include a space after the 9:

In swift:

var str = "test Test 333 9599 999";
val strippedStr = str.stringByReplacingOccurrencesOfString("[^0-9 ]", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range:nil);
// strippedStr = " 33 9599 999"

While this leaves the leading space, you could apply a whitespace trimming to deal with that:

strippedStr.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
// strippedStr = "33 9599 999"
Jbryson
  • 2,875
  • 1
  • 31
  • 53
4
// Our test string
NSString* _bbox = @"Test 333 9599 999";

// Remove everything except numeric digits and spaces
NSString *strippedBbox = [_bbox stringByReplacingOccurrencesOfString:@"[^\\d ]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [_bbox length])];
// (Optional) Trim spaces on either end, but keep spaces in the middle
strippedBbox = [strippedBbox stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

// Print result
NSLog(@"%@", strippedBbox);

This prints 333 9599 999, which I think is what you're after. It also removes non numeric characters that may be in the middle of the string, such as parentheses.

WDUK
  • 18,870
  • 3
  • 64
  • 72
4

For Swift 3.0.1 folks

var str = "1 3 6 .599.188-99 "
    str.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression, range: nil)

Output: "13659918899"

This also trim spaces from string

Community
  • 1
  • 1
jaikme
  • 93
  • 5
3

try using NSScanner

NSString *originalString = @"(123) 123123 abc";
NSMutableString *strippedString = [NSMutableString 
    stringWithCapacity:originalString.length];

NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet 
    characterSetWithCharactersInString:@"0123456789 "];

while ([scanner isAtEnd] == NO) {
    NSString *buffer;
    if ([scanner scanCharactersFromSet:numbers intoString:&buffer]) {
        [strippedString appendString:buffer];
    } else {
        [scanner setScanLocation:([scanner scanLocation] + 1)];
    }
}

NSLog(@"%@", strippedString); // "123123123"
dreamlax
  • 93,976
  • 29
  • 161
  • 209
Pawan Rai
  • 3,434
  • 4
  • 32
  • 42
0
NSMutableString strippedBbox = [_bbox mutableCopy];
NSCharacterSet* charSet = [NSCharacterSet characterSetWithCharactersInString:@"1234567890 "].invertedSet;

NSUInteger start = 0;
NSUInteger length = _bbox.length;

while(length > 0)
{
    NSRange range = [strippedBbox rangeOfCharacterFromSet:charSet options:0 range:NSMakeRange(start, length)];

    if(range.location == NSNotFound)
    {
        break;
    }

    start += (range.location + range.length);
    length -= range.length;

    [strippedBbox replaceCharactersInRange:range withString:@""];
}
Léo Natan
  • 56,823
  • 9
  • 150
  • 195
0

In brief, you can use NSCharacterSet to examine only those chars that are interesting to you and ignore the rest.

- (void) stripper {

    NSString *inString = @"A1 B2 C3 D4";
    NSString *outString = @"";

    for (int i = 0; i < inString.length; i++) {

        if ([[NSCharacterSet whitespaceCharacterSet] characterIsMember:[inString characterAtIndex:i]] || [[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[inString characterAtIndex:i]]) {

            outString = [outString stringByAppendingString:[NSString stringWithFormat:@"%c",[inString characterAtIndex:i]]];
        }
    }
}
Thompson
  • 1,098
  • 11
  • 25