0

I have this text

1111222233334444

And i need to get this result

1111 2222 3333 4444

Please give me the formula of NSRegularExpression.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
developer_I1
  • 65
  • 1
  • 8
  • I would recommend making an attempt, or showing what you tried. You're not going to get an answer by just asking SO to write code for you. There's documentation on NSRegularExpression here: https://developer.apple.com/documentation/foundation/nsregularexpression?language=objc and you can use something like this site: https://regex101.com to test out your possible regex – R4N Feb 07 '20 at 16:26

1 Answers1

1

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”.

Rob
  • 415,655
  • 72
  • 787
  • 1,044