Группы захвата, не работающие в NSRegularExpression

Почему этот код только выплевывает все регулярное выражение вместо группы захвата?

Ввод

@"A long string containing Name:</td><td>A name here</td> amongst other things"

Ожидаемый результат

A name here

Фактический выход

Name:</td><td>A name here</td>

код

NSString *htmlString = @"A long string containing Name:</td><td>A name here</td> amongst other things";
NSRegularExpression *nameExpression = [NSRegularExpression regularExpressionWithPattern:@"Name:</td>.*\">(.*)</td>" options:NSRegularExpressionSearch error:nil];

NSArray *matches = [nameExpression matchesInString:htmlString
                                  options:0
                                    range:NSMakeRange(0, [htmlString length])];
for (NSTextCheckingResult *match in matches) {
    NSRange matchRange = [match range];
    NSString *matchString = [htmlString substringWithRange:matchRange];
    NSLog(@"%@", matchString);
}

Код, взятый из документов Apple. Я знаю, что есть другие библиотеки, но я хочу придерживаться того, что встроено для этой задачи.

Ответ 1

Вы получите доступ к первому диапазону групп, используя:

for (NSTextCheckingResult *match in matches) {
    //NSRange matchRange = [match range];
    NSRange matchRange = [match rangeAtIndex:1];
    NSString *matchString = [htmlString substringWithRange:matchRange];
    NSLog(@"%@", matchString);
}

Ответ 2

Не разбирайте HTML с регулярными выражениями или NSScanner. Вниз этот путь - безумие.

Это было задано много раз на SO.

разбор HTML на iPhone

Данные, которые я собираю, так же просты, как <td>Name: A name</td> и я считайте его достаточно простым, чтобы просто использовать регулярные выражения вместо включая полноэкранный анализатор HTML в проекте.

До вас, и я сильный сторонник "для выхода на рынок имеет огромное преимущество".

Разница заключается в том, что с правильным парсером HTML вы рассматриваете структуру документа. Используя регулярные выражения, вы полагаетесь на документ, который никогда не меняет формат таким образом, который синтаксически в противном случае совершенно корректен.

т.е. что, если вход был <td class="name">Name: A name</td>? Ваш синтаксический анализатор регулярных выражений просто сломался на входе, который является как допустимым HTML, так и с точки зрения содержимого тега, идентичным исходному входу.

Ответ 3

HTML не является регулярным языком и не может быть правильно проанализирован с использованием регулярных выражений. Здесь классический ответ SO, объясняющий это обычное неверное программирование.

Ответ 4

В swift3

//: Playground - noun: a place where people can play

import UIKit

/// Two groups. 1: [A-Z]+, 2: [0-9]+
var pattern = "([A-Z]+)([0-9]+)"

let regex = try NSRegularExpression(pattern: pattern, options:[.caseInsensitive])

let str = "AA01B2C3DD4"
let strLen = str.characters.count
let results = regex.matches(in: str, options: [], range: NSMakeRange(0, strLen))

let nsStr = str as NSString

for a in results {

    let c = a.numberOfRanges 
    print(c)

    let m0 = a.rangeAt(0)  //< Ex: 'AA01'
    let m1 = a.rangeAt(1)  //< Group 1: Alpha chars, ex: 'AA'
    let m2 = a.rangeAt(2)  //< Group 2: Digital numbers, ex: '01'
    // let m3 = a.rangeAt(3) //< Runtime exceptions

    let s = nsStr.substring(with: m2)
    print(s)
}