Использование групп захвата в шаблоне NSRegularExpression

Является ли регулярное выражение следующей формы законным в Obj C?

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

Я знаю, что это допустимо в JS с \1 вместо $1, но мне не повезло с Obj C.


person puzzl    schedule 09.03.2015    source источник
comment
Вы читали NSRegularExpression документы и следили за ними? ссылка в первом абзаце на синтаксис регулярного выражения ICU?   -  person CRD    schedule 09.03.2015
comment
Покажите код, который вы пытаетесь; и нет, это регулярное выражение не будет работать в Objective-C.   -  person l'L'l    schedule 09.03.2015
comment
Я обязан предупредить вас, чтобы вы не анализировали HTML с регулярными выражениями. HTML не является обычным языком.   -  person Joe    schedule 09.03.2015
comment
Регулярное выражение, которое я пишу, не предназначено для анализа HTML, я использую здесь HTML в качестве примера, потому что оно намного понятнее, чем регулярное выражение, которое я использую. Да, я прочитал документы, и неясно, поддерживается ли это, поскольку раздел «Формат сопоставления шаблонов» идет сразу после других таблиц синтаксиса и не указывает, допустимо ли это в шаблоне или нет. Все, что я спрашиваю, это можете ли вы использовать предыдущую группу захвата в шаблоне.   -  person puzzl    schedule 10.03.2015
comment
В таком случае используйте \1 ( @"... </\\1>" ) вместо $1.   -  person Joe    schedule 10.03.2015
comment
Из первой таблицы метасимволов в документах: \n Back Reference. Совпадение со всем, с чем совпала n-я группа захвата. n должно быть числом › 1 и ‹ общее количество групп захвата в шаблоне.   -  person CRD    schedule 10.03.2015
comment
@Joe Вы должны опубликовать это как ответ.   -  person Rob    schedule 10.03.2015


Ответы (2)


NSRegularExpression использует Регулярные выражения ICU, использующие синтаксис \n для обратных ссылок, где n – n-я группа захвата.

<(img|a|div).*?>.*?</\\1>
person Joe    schedule 18.03.2015

Да, я верю, что вы можете работать с группами захвата. Мне пришлось немного поработать с ними некоторое время назад, и у меня есть пример:

-(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, которое задокументировано с помощью:

Результат должен иметь хотя бы один диапазон, но может быть и больше (например, для представления групп захвата регулярных выражений).

В моем примере выше (Примечание: я анализирую HTML, но использую дополнительный модуль, который просматривает HTML с помощью запросов XPath, TFHpple — спасение, если вам абсолютно необходимо анализировать HTML), я использую -[NSRegularExpression firstMatchInString:options:range:] для проверки первого экземпляра тега, соответствующего моему шаблону регулярного выражения. Из этого NSTextCheckingResult я вытаскиваю правильный индекс интересующей меня группы захвата (в данном случае [regexResults rangeAtIndex:1])

Но добраться до этого момента было огромной головной болью. Но чтобы убедиться, что вы получаете правильные выражения, я настоятельно рекомендую использовать Regex101 с настройкой Python, а затем передать уточненный регулярное выражение в Шаблоны (Mac App Store)

Если вам нужен полный вид, у меня есть довольно подробный проект здесь, но имейте в виду, что это все еще WIP.

person Louis Tur    schedule 09.03.2015
comment
Это вообще не отвечает на вопрос. Однако Джо выше был прав, используя только \1 (или, что более реалистично, \\1) вместо $1, однако он не опубликовал это как ответ, поэтому я не могу проголосовать за него. - person puzzl; 10.03.2015