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

This regular expression works for me when I test it in PHP, but it does not work in Objective-C:

(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?) 

I tried escaping escape characters, but that doesn't help either. Should I avoid any other character?

This is my code in Objective-C:

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

- UPDATE -

This regular expression returns (in PHP) an array with the values ​​"domain-name" and "tld.tld2", but in Objective-C I get only one value: "domain-name.tld.tld2"

- UPDATE 2 -

This regular expression extracts the "domain name" and "TLD" from the string:

  • domain.com = (domain, com)
  • domain.co.uk = (domain, co.uk)
  • -test-domain.co.u = (test-domain, co)
  • -test-domain.co.uk- = (test-domain, co.uk)
  • -test-domain.co.uk = (test-domain, co)
  • -test-domain.co-m = (test domain)
  • -test-domain-.co.uk = (test domain)

it accepts a valid domain name (not beginning and not ending with "-" and between 2 and 63 characters) and up to two parts of the TLD if the parts are valid (at least two characters containing only letters and numbers)

Hope this explanation helps.

+43
regex ios objective-c nsregularexpression
Feb 14 '12 at 11:43
source share
2 answers

A NSTextCheckingResult has several elements obtained by indexing into it.

[match rangeAtIndex:0]; - full match.
[match rangeAtIndex:1]; (if it exists) is the first match of the capture group.
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

Verify that the matching ranges are valid.

Simply put:

 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 NSString let 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

Simply put:

 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

+70
Feb 14 2018-12-12T00:
source share

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

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

It will also help if you can explain what you are trying to achieve. Do you have any test equipment?

+11
Feb 14 '12 at 11:52
source share



All Articles