2017-05-22 2 views
-2

Chaîne: '<td attr="0">str1</td><td attr="5">str2</td><td attr="7">str2</td><td attr="9">str4</td>'python expression régulière non gourmand recherche trop de données

Je veux rechercher et obtenir seulement première balise « td » qui contient du texte: « str2 ». alors j'ai essayé deux différentes expressions non cupides comme ci-dessous:

>>> mystring = '<td attr="0">str1</td><td attr="5">str2</td><td attr="7">str2</td><td attr="9">str4</td>' 
>>> print re.search("(<td.*?str2.*?</td>)",mystring).group(1) 
<td attr="0">str1</td><td attr="5">str2</td> 
>>> print re.search(".*(<td.*?str2.*?</td>).*",mystring).group(1) 
<td attr="7">str2</td> 

Ici je sortie comme "<td attr="5">str2</td>" attendais, parce que je l'ai utilisé l'expression non gourmande dans l'expression régulière. Quel est le problème ici et comment extraire le résultat de recherche attendu?

Note: Je ne peux pas utiliser l'analyseur html parce que mon réel jeu de données ne sont pas tellement formaté pour l'analyse syntaxique xml

Répondre

-1

Utilisation [^>] au lieu de .:

>>> print re.search("(<td[^>]*?>str2.*?</td>)",mystring).group(1) 
<td attr="5">str2</td> 

(see demo)

Ou, mieux, utilisez HTMLParser.

EDIT: Cette expression rationnelle correspond à même sous-tags:

(<td[^<]*?(?:<(?!td)[^<]*?)*str2.*?</td>) 
+0

serait apprécié une raison pour le downvote. – horcrux

+0

Merci pour votre réponse. Je n'ai pas utilisé l'analyseur html car mon jeu de données n'est pas au format xml et l'analyseur échoue. Également dans la balise , il existe une chance d'avoir plusieurs autres balises enfant comme . Mais le point principal est que je veux aller chercher la première balise "td" qui contient du texte: "str2". – dagpag

+0

Je comprends. Je pense que [ceci] (https://regex101.com/r/VSPPFa/3) fonctionnera même avec des sous-balises. – horcrux