I have this text
1111222233334444
And i need to get this result
1111 2222 3333 4444
Please give me the formula of NSRegularExpression
.
I have this text
1111222233334444
And i need to get this result
1111 2222 3333 4444
Please give me the formula of NSRegularExpression
.
The regular expression pattern might be something like:
^([0-9]{4})([0-9]{4})([0-9]{4})([0-9]{4})$
The ^
matches the start of the string, each [0-9]{4}
finds a sequence of four digits, the (
and )
are “capturing” these groups of digits as individual ranges, and the $
matches the end of the string.
Thus, with NSRegularExpression
, it might be something like:
- (NSString *)formatCreditCard:(NSString *)string {
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^([0-9]{4})([0-9]{4})([0-9]{4})([0-9]{4})$" options:kNilOptions error:&error];
if (error) {
NSLog(@"error: %@", error);
return nil;
}
NSRange range = NSMakeRange(0, string.length);
NSTextCheckingResult *match = [regex firstMatchInString:string options:kNilOptions range:range];
if (!match) {
return nil;
}
NSMutableArray <NSString *>*results = [[NSMutableArray alloc] init];
for (NSInteger index = 1; index <= regex.numberOfCaptureGroups; index++) {
NSRange range = [match rangeAtIndex:index];
[results addObject:[string substringWithRange:range]];
}
return [results componentsJoinedByString:@" "];
}
But you don’t have to get into NSRegularExpression
if you don’t want. You can use stringByReplacingOccurrencesOfString:withString:options:range:
, with the NSRegularExpressionSearch
option:
- (NSString *)formatCreditCard:(NSString *)string {
NSRange range = NSMakeRange(0, string.length);
return [string stringByReplacingOccurrencesOfString:@"^([0-9]{4})([0-9]{4})([0-9]{4})([0-9]{4})$"
withString:@"$1 $2 $3 $4"
options:NSRegularExpressionSearch
range:range];
}
FWIW, the Swift renditions might look like:
func format(creditCardNumber string: String) -> String? {
guard
let regex = try? NSRegularExpression(pattern: "^([0-9]{4})([0-9]{4})([0-9]{4})([0-9]{4})$"),
let match = regex.firstMatch(in: string, range: NSRange(string.startIndex..., in: string)),
match.numberOfRanges > 1
else {
return nil
}
return (1..<match.numberOfRanges)
.compactMap { Range(match.range(at: $0), in: string) }
.map { string[$0] }
.joined(separator: " ")
}
or
func format(creditCardNumber string: String) -> String {
string.replacingOccurrences(of: "^([0-9]{4})([0-9]{4})([0-9]{4})([0-9]{4})$",
with: "$1 $2 $3 $4",
options: .regularExpression)
}
Above, I’ve assumed that this was a credit card number that you wanted to format, but if that’s the case, please note that this simple XXXX XXXX XXXX XXXX
format is not sufficient. Not not all credit card numbers are formatted that way (e.g. American Express numbers are XXXX XXXXXX XXXXX
).
There are lots of different formats and credit card number lengths (see Payment card number). You might want to just find a library that gets you out of the weeds of this. See Formatting a UITextField for credit card input like (xxxx xxxx xxxx xxxx) for more information or search the web for “iOS credit card formatter”.