How to write regular expressions in Objective C (NSRegularExpression)? How to write regular expressions in Objective C (NSRegularExpression)? ios ios

How to write regular expressions in Objective C (NSRegularExpression)?


A NSTextCheckingResult has multiple items obtained by indexing into it.

[match rangeAtIndex:0]; is the full match.
[match rangeAtIndex:1]; (if it exists) is the first capture group match.
etc.

You can use something like this:

NSString *searchedString = @"domain-name.tld.tld2";NSRange   searchedRange = NSMakeRange(0, [searchedString length]);NSString *pattern = @"(?:www\\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\\.?((?:[a-zA-Z0-9]{2,})?(?:\\.[a-zA-Z0-9]{2,})?)";NSError  *error = nil;NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern: pattern options:0 error:&error];NSArray* matches = [regex matchesInString:searchedString options:0 range: searchedRange];for (NSTextCheckingResult* match in matches) {    NSString* matchText = [searchedString substringWithRange:[match range]];    NSLog(@"match: %@", matchText);    NSRange group1 = [match rangeAtIndex:1];    NSRange group2 = [match rangeAtIndex:2];    NSLog(@"group1: %@", [searchedString substringWithRange:group1]);    NSLog(@"group2: %@", [searchedString substringWithRange:group2]);}

NSLog output:

match: domain-name.tld.tld2
domain-name
tld.tld2

Do test that the match ranges are valid.

More simply in this case:

NSString *searchedString = @"domain-name.tld.tld2";NSRange   searchedRange = NSMakeRange(0, [searchedString length]);NSString *pattern = @"(?:www\\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\\.?((?:[a-zA-Z0-9]{2,})?(?:\\.[a-zA-Z0-9]{2,})?)";NSError  *error = nil;NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];NSTextCheckingResult *match = [regex firstMatchInString:searchedString options:0 range: searchedRange];NSLog(@"group1: %@", [searchedString substringWithRange:[match rangeAtIndex:1]]);NSLog(@"group2: %@", [searchedString substringWithRange:[match rangeAtIndex:2]]);

Swift 3.0:

let searchedString = "domain-name.tld.tld2"let nsSearchedString = searchedString as NSStringlet searchedRange = NSMakeRange(0, searchedString.characters.count)let pattern = "(?:www\\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\\.?((?:[a-zA-Z0-9]{2,})?(?:\\.[a-zA-Z0-9]{2,})?)"do {    let regex = try NSRegularExpression(pattern:pattern, options: [])    let matches = regex.matches(in:searchedString, options:[], range:searchedRange)    for match in matches {        let matchText = nsSearchedString.substring(with:match.range);        print("match: \(matchText)");        let group1 : NSRange = match.rangeAt(1)        let matchText1 = nsSearchedString.substring(with: group1)        print("matchText1: \(matchText1)")        let group2 = match.rangeAt(2)        let matchText2 = nsSearchedString.substring(with: group2)        print("matchText2: \(matchText2)")    }} catch let error as NSError {    print(error.localizedDescription)}

print output:

match: domain-name.tld.tld2
matchText1: domain-name
matchText2: tld.tld2

More simply in this case:

do {    let regex = try NSRegularExpression(pattern:pattern, options: [])    let match = regex.firstMatch(in:searchedString, options:[], range:searchedRange)    let matchText1 = nsSearchedString.substring(with: match!.rangeAt(1))    print("matchText1: \(matchText1)")    let matchText2 = nsSearchedString.substring(with: match!.rangeAt(2))    print("matchText2: \(matchText2)")} catch let error as NSError {    print(error.localizedDescription)}

print output:

matchText1: domain-name
matchText2: tld.tld2


According to Apple's documentation, these characters must be quoted (using \) to be treated as literals:

* ? + [ ( ) { } ^ $ | \ . /

It would also help if you could explain what you are trying to achieve. Do you have any test fixtures?