Группы захвата, не работающие в 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)
}
Ответ 5
Или просто используйте
[htmlString firstMatchedGroupWithRegex:@"Name:</td>.*\">(.*)</td>"]
из этой категории https://github.com/damienromito/NSString-Matcher