Citation:
fait par quelqu'un qui maitrise, cela ne doit pas faire plus que quelques lignes de code
Bon, bon.... Mais j’attends de voir le code...
Ce que j’aime avec Python, c’est que même avec une connaissance très parcellaire de ce langage, j’arrive à faire des choses rapidement ; et de plus, quand c’est pour faire quelque chose de nouveau, je parviens à apprendre ce qu’il faut rapidement et sans excéder les capacités de mes petits neurones.
Citation:
le document HTMLDocument permet de faire toute sorte de choses comme insérer des valeurs, des balises en enlever etc...
je ne conteste pas que ce doit être intéressant de disposer d’un tel outil. Quand c’est nécessaire. J’avoue avoir une petit tendance à vouloir faire les choses par moi même, en codant moi même ce que je veux, et par fainéantise d’apprendre des extensions et des librairies tierces. Mais ça a ses limites. Je demande simplement qu’on reconnaisse que quand il faut faire une chose simple, ça peut être mieux de ne pas s’embarasser avec un gros attirail accompagné d’un manuel de plusieurs dizaines de pages. C’est ce que tu fais au début:
Citation:
Effectivement eyquem, il n'y a pas de doute sur le fait que dans le cas de la question initiale, l'utilisation d'une expression régulière appliquée sur une lecture texte du fichier ou d'un flux reste sans doute la plus simple et facile à mettre en oeuvre.
Mais ensuite, je ne comprends pas ceci:
Citation:
il me semblait plus propice d'aborder l'aspect HTML de la chose.
Et pourquoi donc ? HTML ou pas, un texte est un texte. Si on veut un petit bout du texte , pourquoi s’enquiquiner à tenir compte de sa structure HTML ???
Citation:
Quand aux expressions régulières, je n'ai aucun doute sur leur puissance mais la complexité de leur syntaxe qui change d'un langage à l'autre est du moins pour moi un véritable cauchemar.
Ah oui, c’est un handicap. Pour ma part, j’adore les regex.
Il est vrai que je ne les utilise pas dans le cadre de plusieurs langages. je les connais surtout en Python, un peu en PHP, je me suis à les étudier en Perl. Ça peut devenir indigeste, je concède.
Citation:
si on y regarde de près, tout ce qui concerne la reconnaissance de la balise concernée ne se trouve que dans le dernier bloc de codes de la boucle de lecture du bloc BODY.
Oui mais si on enlève le reste, ça ne marcherait plus, n’est ce pas ?
Il y a d'un coté le nombre d’actions qui doivent être réalisées par un programme, mais je ne pensais pas à ça (je ne sais pas comment sont liées le nombre d’actions exécutées et le nombre d’instructions visbles dans le script, d'ailleurs), je pensais d'un autre coté au nombre de caractères qu’il faut taper à la main.
Citation:
si bien que de la balise <HTML> à la balise </HTML> on se retrouve avec 'une seule ligne' de texte. Dans ce cas, il faudra bien même avec une expression régulière, du moins pur ce que j'en connais, comptabiliser le nombre de balise recherchée dans la même ligne et les passer en revue une après l'autre...
passer en revue, c’est bien ce que font la fonction findall() de Python, preg_match_all() de PHP, etc sans se laisser impressioner par la présence ou non de fins de ligne, qui ne sont après tout que des caractéres ’\r’ ou ’\n’ noyés dans le “texte“
Citation:
Pourriez-vous nous montrer à quoi ressemblerait l'expression régulière qui récupererait tout ce qui se trouve dans la balise span, mais en enlevant l'éventuelle présence d'un autre balisage comme ce cas par exemple :
<span class="planet-name"><I>planete terre</I></span>
voir ça :
<span class="planet-name"><U><I>planete toto</I></U></span>
???
Ah, très bien, rien de tel qu’un petit défi pour voir de quoi est capable une regex.
Nuance: une expression régulière n’enlève rien, il faut la définir de façon qu’un groupe capte ce qu l’on veut en évitant de capter ce qu’il y a autour.
1) Ceci fait ce que tu as demandé:
Code:
1 2 3 4 5 6 7 8 9
| import re
uh = '''voici un bon exercice
chercher dans <span class="planet-name"><U><I>planete toto</I></U></span> la planete
toto sans recuperer les balise U et les I'''
RE = '<span .*?planet-name[^>]*>(<([^>]+)>)*([^<]+)(</([^>]+)>)*</span>'
pat = re.compile(RE)
print (pat.search(uh).groups()) |
Résultat:
Code:
('<I>', 'I', 'planete toto', '</U>', 'U')
Il suffit de prendre le groupe 3: pat.search(uh).group(3)
Dans cette RE:
(<([^>]+)>)* capte les éventuels <U> et <I> et autres <jur647vvd> entre la balise d’ouverture span et ce que l’on veut attraper par ([^<]+)
Après ([^<]+) , il y a (</([^>]+)>) , avec un / supplémentaire : on pourrait ne pas mettre le / , il serait représenté par [^>] tout aussi bien. Cependant, le mettre augmente la fiabilité de la regex.
[^>] signifie “n’importe quel caractère , sauf le >
[^>a9] signifie “n’importe quel caractère sauf les 3 caractères > a 9
Une paire de crochet définit UN caractère: c’est un point qui est difficilement assimilé car une paire de crochets définit la classe de caractères permis pour LE caractère à la position concernée dans la chaîne explorée.
Ainsi [7 helix8] permet les caractères 7 8 blanc l i x e h :
[7 helix8] {4} matche avec ’he78’ , ’h8ix’ , ’l8 8’ etc....
mais pas avec ’heYi’
2) La regex construite avec cette RE ne permet cependant pas de capter la portion voulue quand elle comporte le caractère ’<’
La regex va matcher avec
’<span class="planet-name"><U><I>planete to>to</I></U></span>’
mais pas avec
<span class="planet-name"><U><I>plan<ete toto</I></U></span>
Code:
1 2 3 4 5 6 7 8 9
| import re
uhVV = '''une chaine un peu plus vicieuse
a cause de < et > dans la portion recherchee
c'est <span class="planet-name"><U><I>plan<ete toto</I></U></span>jhgfghgdjhyd</span>'''
RE = '<span .*?planet-name[^>]*>(<([^>]+)>)*([^<]+)(</([^>]+)>)*</span>'
pat = re.compile(RE)
print (pat.search(uhVV).groups()) |
Résultat:
Code:
1 2 3 4
| Traceback (most recent call last):
File "C:\Python31\progs 31\balises.py", line 9, in <module>
print (pat.search(uhVV).groups())
AttributeError: 'NoneType' object has no attribute 'groups' |
3) Par contre, voici la preuve du danger de ne pas mettre un caractere quand on le peut (ici le /)
Code:
1 2 3 4 5 6 7 8 9
| import re
uhVV = '''une chaine un peu plus vicieuse
a cause de < et > dans la portion recherchee
c'est <span class="planet-name"><U><I>plan<ete toto</I></U></span>jhgfghgdjhyd</span>'''
RE = '<span .*?planet-name[^>]*>(<([^>]+)>)*([^<]+)(<([^>]+)>)*</span>'
pat = re.compile(RE)
print (pat.search(uhVV).groups()) |
Dans ce code y a plus le /
Résultat:
Code:
('<I>', 'I', 'plan', '</U>', '/U')
on attrape quelque chose mais ce n'est pas bon.
« on pourrait ne pas mettre le / , il serait représenté par [^>] tout aussi bien. Cependant, le mettre augmente la fiabilité de la regex.
»
4) Pour y arriver, il faut modifier la RE:
Code:
1 2 3 4 5 6 7 8 9 10
| import re
uhVV = '''une chaine un peu plus vicieuse
a cause de < et > dans la portion recherchee
c'est <span class="planet-name"><U><I>plan<ete toto</I></U></span>jhgfghgdjhyd</span>'''
REVV = '<span .*?planet-name[^>]*>(<([^>]+)>)*(.+)(?(1)</\\2>)(<([^>]+)>)*</span>'
patVV = re.compile(REVV)
print (patVV.search(uhVV).groups()) |
Résultat:
Code:
('<I>', 'I', 'plan<ete toto', '</U>', '/U')
(?(1)</\\2>) signifie ceci:
(?(1) ... = s’il y a eu un groupe 1 qui a matché quelque chose
alors est ce qu’on trouve à cette position actuelle un motif </\\2> ?
Ce motif ce sont le caractère < puis le caractère /
puis le groupe 2 trouvé (mais ça pourrait être autre chose)
et enfin le caractere >
Les groupe 1 et 2 trouvés, ce sont les derniers, quand il y en a plusieurs, en l’occurence '<I>' et 'I'
On fait suivre (?(1)</\\2>) de (<([^>]+)>)*
pour matcher avec d'éventuels </quch> supplémentaires (dans notre cas il s'agit de </U> )
5) Dans un vrai code, on écrira
Code:
1 2 3 4 5 6 7 8 9 10
| import re
uhVV = '''une chaine un peu plus vicieuse
a cause de < et > dans la portion recherchee
c'est <span class="planet-name"><U><I>plan<ete toto</I></U></span>jhgfghgdjhyd</span>'''
REVV = '<span .*?planet-name[^>]*>(?:<([^>]+)>)*(.+)(?(1)</\\1>)(?:<(?:[^>]+)>)*</span>'
patVV = re.compile(REVV)
print (patVV.search(uhVV).groups()) |
?: en tête de portion parenthésée signale en effet: ne pas enregistrer ce contenu de parenthèse dans un groupe.
resultat
Code:
('I', 'plan<ete toto')
pour éviter au programme de faire des enregistrements de groupes.
En n'oubliant pas de changer (?(1)</\\2>) en (?(1)</\\1>) puisque la modification change la numérotation des groupes.
Avec cette derniere RE, la chaîne recherchée est dans le groupe 2:
patVV.search(uhVV).group(2)
Ce qui répond à ta demande.
NB: c'est 50 fois plus long à expliquer qu’à faire.
PS Tu peux me tutoyer, le vouvoiement me fait bizarre sur un forum.
.