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?