 <p>Here's a unicode aware implementation as a category on <code>NSString</code>:</p> <pre><code>@interface NSString (NRStringFormatting) - (NSString *)stringByFormattingAsCreditCardNumber; @end @implementation NSString (NRStringFormatting) - (NSString *)stringByFormattingAsCreditCardNumber { NSMutableString *result = [NSMutableString string]; __block NSInteger count = -1; [self enumerateSubstringsInRange:(NSRange){0, [self length]} options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { if ([substring rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]].location != NSNotFound) return; count += 1; if (count == 4) { [result appendString:@" "]; count = 0; } [result appendString:substring]; }]; return result; } @end </code></pre> <p>Try it with this test string:</p> <pre><code>NSString *string = @"ab 132487 387 e e e "; NSLog(@"%@", [string stringByFormattingAsCreditCardNumber]); </code></pre> <p>The method works with non-BMP characters (i.e. emoji) and handles existing white space.</p>