在 NSRegularExpression 模式中使用捕获组

Using capture groups within an NSRegularExpression pattern

以下形式的正则表达式在 Obj C 中是否合法?

"<(img|a|div).*?>.*?</>"

我知道它在 JS 中使用 \1 而不是 $1 是有效的,但我在 Obj C 中运气不佳。

是的,我相信您可以使用捕获组。不久前我不得不和他们一起工作,我有一个例子:

-(NSString *) extractMediaLink:(NSString *)link withRegex:(NSString *)regex{
    NSString * utf8Link = [link stringByRemovingPercentEncoding]; 
    NSError * regexError = nil;

    NSRegularExpression * regexParser = [NSRegularExpression regularExpressionWithPattern:regex 
                                                                                  options:NSRegularExpressionCaseInsensitive|NSRegularExpressionUseUnixLineSeparators
                                                                                    error:&regexError];
    NSTextCheckingResult * regexResults =  [regexParser firstMatchInString:utf8Link
                                                                   options:0
                                                                     range:NSMakeRange(0, [utf8Link length])];

    NSString * matchedResults = [utf8Link substringWithRange:[regexResults rangeAtIndex:1]]; // the second capture group will always have the ID

    return matchedResults.length ? matchedResults : @"";
}

当您使用 NSRegularExpression 的实例生成 NSTextCheckingResult 时,NSTextCheckingResult 具有 numberOfRanges 的 属性,记录为:

A result must have at least one range, but may optionally have more (for example, to represent regular expression capture groups).

在我上面的例子中(注意:我恰好在解析HTML,但是使用了一个通过XPath查询遍历HTML的附加pod,TFHpple - - 如果您绝对必须解析 HTML),我会使用 -[NSRegularExpression firstMatchInString:options:range:] 来检查与我的正则表达式模式匹配的标签的第一个实例。从中 NSTextCheckingResult 我提取了我感兴趣的捕获组的正确索引(在本例中,[regexResults rangeAtIndex:1]

但是,走到这一步是一个巨大的痛苦。但为了确保您获得正确的表达方式,我强烈建议您使用 Regex101 with the Python setting, and then passing the refined regex into Patterns (Mac App Store)

如果您想要完整的外观,我有一个相当详细的项目 here,但请记住它仍然是一个 WIP。

NSRegularExpression uses ICU Regular Expressions 对反向引用使用 \n 语法,其中 n 是第 n 个捕获组。

<(img|a|div).*?>.*?</\1>