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

前端 未结 2 2028
隐瞒了意图╮
隐瞒了意图╮ 2020-11-30 21:52

I have this regex working when I test it in PHP but it doesn\'t work in Objective C:

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

        
相关标签:
2条回答
  • 2020-11-30 22:29

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

    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

    0 讨论(0)
  • 2020-11-30 22:30

    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?

    0 讨论(0)
提交回复
热议问题