当我在PHP中测试这个正则表达式时,它可以工作,但在Objective C中不工作:

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

我试着逃离逃跑的角色,但也没用.我应该逃离其他角色吗?

这是我在目标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);
}

--更新--

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

--更新2--

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

  • 领域com=(域,com)
  • 领域co.uk=(域名,co.uk)
  • -测试域.co.u=(测试域,co)
  • -测试域.co.uk-=(测试域,co.uk)
  • -测试域.co.u-k=(测试域,co)
  • -测试域.co-m=(测试域)
  • -测试域-.co.uk=(测试域)

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

希望这个解释能有所帮助.

推荐答案

NSTextCheckingResult有多个通过索引获得的项目.

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

你可以这样使用:

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输出:

匹配:域名.tld.tld2

测试匹配范围是否有效.

更简单地说,在这种情况下:

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

打印输出:

匹配:域名.tld.tld2

更简单地说,在这种情况下:

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

打印输出:

matchText1:域名

Objective-c相关问答推荐

Objective-C 静态、外部、公共变量

当前周开始和结束日期

目标 C:在不离开应用程序的情况下发送Electron邮件

将 NSNumber 转换为 NSDecimalNumber

BSXPCMessage 收到消息错误:连接中断

如何在另一个视图中获取视图的框架?

UIWebView 不会zoom 内容以适应

iOS NSLayoutConstraint 使用 constraintWithItem 固定宽度

无法访问 dispatch_async 中的全局变量:变量不可赋值(缺少 _block 类型说明符)

了解按位与运算符

如何用 Java 开发 iPhone 应用程序?

以流畅的动画显示/隐藏导航栏

将块存储在数组中

如何将 NSOperationQueue 与 NSURLSession 一起使用?

Objective-C 异常

为什么 Select Emacs/Vim/Textmate? Xcode 还不够好吗?

字符串常量和字符串文字有什么区别?

CMTime 秒输出

带有 UIImage 的 UIBarButtonItem 始终着色 iOS 7

找出用户是否按下了 uinavigationcontroller 中的后退按钮?