如何在Objective C(NSRegularExpression)中编写正则表达式? [英] How to write regular expressions in Objective C (NSRegularExpression)?

查看:110
本文介绍了如何在Objective C(NSRegularExpression)中编写正则表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在PHP中测试它时,我有这个正则表达式工作,但它在目标C中不起作用:

 (? :www\) -  [α-ZA-Z0-9  - ] {2,63};  - )\((((!)(小于?!):?[A-ZA-Z0 -9] {2,})?(?:\。[a-zA-Z0-9] {2,})?)

我试图逃避转义字符,但这也无济于事。我应该逃避任何其他角色吗?



这是我在目标C中的代码:

  NSMutableString * searchingString = [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:searchingString options:0 range:NSMakeRange(0,[searchingString length])];
for(NSTextCheckingResult *匹配匹配)
{
NSString * matchText = [searchingString substringWithRange:[match range]];
NSLog(@match:%@,matchText);
}

- 更新 -



这个正则表达式返回(在PHP中)值为domain-name和tld.tld2的数组,但在Objective C中我只得到一个值:domain-name.tld.tld2



- 更新2 -



此正则表达式从字符串中提取域名和TLD:




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



它采用有效的域名(不是以' - '开头或结尾,长度在2到63个字符之间),如果部分有效,则最多为TLD的两个部分(至少两个)只包含字母和数字的字符)



希望这个解释有所帮助。

解决方案

A NSTextCheckingResult 通过索引获得多个项目。



[match rangeAtIndex:0]; 是完全匹配。

[match rangeAtIndex:1]; (如果存在)是第一个捕获组匹配。

等。



您可以使用以下内容:

  NSString * searchingString = @domain-name.tld.tld2; 
NSRange searchingRange = NSMakeRange(0,[searchingString 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:searchingString options:0 range:searchingRange];
for(NSTextCheckingResult *匹配中匹配){
NSString * matchText = [searchingString substringWithRange:[match range]];
NSLog(@match:%@,matchText);
NSRange group1 = [match rangeAtIndex:1];
NSRange group2 = [match rangeAtIndex:2];
NSLog(@group1:%@,[searchingString substringWithRange:group1]);
NSLog(@group2:%@,[searchingString substringWithRange:group2]);
}

NSLog输出:



< blockquote>

匹配:domain-name.tld.tld2

domain-name

tld.tld2


测试匹配范围是否有效。



在这种情况下更简单:

  NSString * searchingString = @domain-name.tld.tld2; 
NSRange searchingRange = NSMakeRange(0,[searchingString 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:searchingString options:0 range:searchingRange];
NSLog(@group1:%@,[searchingString substringWithRange:[match rangeAtIndex:1]]);
NSLog(@group2:%@,[searchingString substringWithRange:[match rangeAtIndex:2]]);




Swift 3.0:




  let searchingString =domain-name.tld.tld2
让nsSearchedString = searchingString为NSString
let searchingRange = NSMakeRange(0,searchingString.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: searchingString,options:[],range:searchingRange)
匹配匹配{
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))
}
}将错误视为NSError {
print(error.localizedDescription)
}

打印输出:


匹配:domain-name.tld.tld2

matchText1 :域名

matchText2:tld.tld2


在这种情况下更简单:

  do {
let regex = try NSRegularExpression(pattern:pattern,options:[])
let match = regex.firstMatch (in:searchingString,options:[],range:searchingRange)

let matchText1 = nsSearchedString.substring(with:match!.rangeAt(1))
print(ma tchText1:\(matchText1))

let matchText2 = nsSearchedString.substring(with:match!.rangeAt(2))
print(matchText2:\(matchText2))

}将错误视为NSError {
print(error.localizedDescription)
}

打印输出:


matchText1:domain-name

matchText2:tld。 tld2



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}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)

I tried escaping the escape characters but that doesn't help either. Should I escape 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 regex returns (in PHP) the array with values "domain-name" and "tld.tld2" but in Objective C i get only one value: "domain-name.tld.tld2"

-- UPDATE 2 --

This regex extracts '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.u-k = (test-domain, co)
  • -test-domain.co-m = (test-domain)
  • -test-domain-.co.uk = (test-domain)

it takes the valid domain name (not starting or ending with '-' and between 2 and 63 characters long), and up to two parts of a TLD if the parts are valid (at least two characters long containing only letters and numbers)

Hope this explanation helps.

解决方案

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

这篇关于如何在Objective C(NSRegularExpression)中编写正则表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆