objective-c regex ios nsregularexpression capture-group

objective c - Los grupos de captura no funcionan en NSRegularExpression



objective-c regex (5)

¿Por qué este código solo muestra toda la coincidencia de expresiones regulares en lugar del grupo de captura?

Entrada

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

Salida esperada

A name here

Salida real

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

Código

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

Código tomado de los documentos de Apple. Sé que hay otras bibliotecas para hacer esto, pero quiero seguir con lo que está integrado en esta tarea.


Accederá al primer rango de grupo usando:

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


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



No analice HTML con expresiones regulares o NSScanner. Por ese camino yace la locura.

Esto se ha preguntado muchas veces en SO.

analizar HTML en el iPhone

Los datos que selecciono son tan simples como <td>Name: A name</td> y creo que es lo suficientemente simple como para usar expresiones regulares en lugar de incluir un analizador de HTML completo en el proyecto.

Depende de usted y soy un firme defensor de que "el primero en llegar al mercado tiene una gran ventaja".

La diferencia es que con un analizador de HTML adecuado, está considerando la estructura del documento. Al usar expresiones regulares, confía en que el documento nunca cambiará el formato de manera que, sintácticamente, sea perfectamente válido.

Es decir, ¿qué ocurre si la entrada es <td class="name">Name: A name</td> ? Su analizador de expresiones regulares simplemente rompió la entrada que es a la vez HTML válido y, desde una perspectiva de contenido de etiqueta, idéntica a la entrada original.