Pourquoi ce code crache-t-il uniquement toute la correspondance d'expression régulière au lieu du groupe de capture?
entrée
@"A long string containing Name:</td><td>A name here</td> amongst other things"
Sortie attendue
A name here
sortie réelle
Name:</td><td>A name here</td>
Code
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);
}
Code tiré de Apple docs. Je sais qu'il existe d'autres bibliothèques pour ce faire, mais je veux m'en tenir à ce qui est intégré pour cette tâche.
Vous accéderez à la première plage de groupe en utilisant:
for (NSTextCheckingResult *match in matches) {
//NSRange matchRange = [match range];
NSRange matchRange = [match rangeAtIndex:1];
NSString *matchString = [htmlString substringWithRange:matchRange];
NSLog(@"%@", matchString);
}
Ne pas analyser HTML avec des expressions régulières ou NSScanner. Sur cette voie se trouve la folie.
Cela a été demandé à plusieurs reprises sur SO.
Les données que je choisis sont aussi simples que
<td>Name: A name</td>
et je pense que c'est assez simple pour simplement utiliser des expressions régulières au lieu d'inclure un analyseur HTML complet dans le projet.
À vous de voir et je suis un ardent défenseur du "premier sur le marché a un énorme avantage".
La différence étant qu'avec un analyseur HTML approprié, vous envisagez la structure du document. À l'aide d'expressions régulières, vous vous fiez au document qui ne change jamais de format de manière syntaxiquement parfaitement valide.
C'est à dire. et si l'entrée était <td class="name">Name: A name</td>
? Votre analyseur d'expressions rationnelles vient de se casser sur une entrée à la fois HTML valide et, du point de vue du contenu des balises, identique à l'entrée d'origine.
HTML n'est pas un langage standard et ne peut pas être correctement analysé à l'aide d'expressions régulières. Voici un classique SO expliquant cette erreur de programmation courante.
Dans 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)
}