Expression régulière

Le
Thoma
Bonsoir,

J'ai découvert les expressions régulières récemment.

Aujourd'hui, j'essaye de les utiliser pour extraire deux champs :

Les deux lignes suivantes sont :

test?champ1=valeur1&champ2=valeur2&champ3=valeur3&champ4=valeur4
test?champ1=valeur1&champ2=valeur2&champ4=valeur4

et je veux extraire "valeur1" et "valeur2".

J'ai crée l'expression suivante :

champ1=(.*)&champ2=(.*)&

Résultat : je récupère bien "valeur1". Tout se complique avec le second
groupe puisque je me retrouve avec "valeur2&champ3=valeur3". Je
m'attendais à n'avoir que "valeur2".

En cherchant sur la toile, j'ai trouvé une histoire de 'greedy' et
'ungreedy'.

Malheureusement, mes essais ne m'ont pas permis de trouver la bonne
expression me permettant d'extraire "valeur1" et "valeur2".

Si quelqu'un a une idée (et surtout une explication), je suis preneur.

D'avance merci

Thoma
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
bruno.desthuilliers
Le #682869
On 28 jan, 21:42, Thoma
Bonsoir,

J'ai découvert les expressions régulières récemment.

Aujourd'hui, j'essaye de les utiliser pour extraire deux champs :

Les deux lignes suivantes sont :

test?champ1=valeur1&champ2=valeur2&champ3=valeur3&champ4=valeur4
test?champ1=valeur1&champ2=valeur2&champ4=valeur4


C'est une requête http GET, ça. Il y a un module dans la stdlib qui
sait les gérer.

et je veux extraire "valeur1" et "valeur2".

J'ai crée l'expression suivante :

champ1=(.*)&champ2=(.*)&

Résultat : je récupère bien "valeur1". Tout se complique avec le sec ond
groupe puisque je me retrouve avec "valeur2&champ3=valeur3". Je
m'attendais à n'avoir que "valeur2".

En cherchant sur la toile, j'ai trouvé une histoire de 'greedy' et
'ungreedy'.

Malheureusement, mes essais ne m'ont pas permis de trouver la bonne
expression me permettant d'extraire "valeur1" et "valeur2".


s = "test?champ1=valeur1&champ2=valeur2&champ3=valeur3&champ4=vale ur4"
m = re.search(r"champ1=(.*)&champ2=(.*?)&", s)
print m.groups()

Si quelqu'un a une idée (et surtout une explication), je suis preneur.


Par défaut, une expression rationnelle essaie de "consommer" le plus
possible de caractères correspondants (d'où le terme 'greedy', ie
'avide'). Dans ton cas, après "champ2=", elle prend tout ce qu'elle
peut, c'est à dire jusqu'au dernier '&' - celui qui est avant
'champ4'. Le modifiuer 'non-greedy' inverse ce comportement, et donne
le résultat attendu. Pour le premier groupe capturant (champ1), le
problème ne se pose pas puisque tu a '&champ2=' juste derrière.

Note que dans le cas présent, tu aurais aussi pu utiliser une classe
complémentée, ie:

r"champ1=(.*)&champ2=([^&]*)"

"[^&]" signifiant "tout sauf &"

Note aussi que les expressions rationnelles ne sont pas forcément la
bonne solution. Dans l'absolu, puisque c'est une requête HTTP, autant
utiliser le module qui va bien (regarde du côté de cgi). A défaut, ç a
se règle aussi très aisément à coup de split:

s = "test?champ1=valeur1&champ2=valeur2&champ3=valeur3&champ4= valeur4"
s1 = s.split("?")[1]
s1
'champ1=valeur1&champ2=valeur2&champ3=valeur3&champ4=valeur4'



s2 = s1.split('&')
s2
['champ1=valeur1', 'champ2=valeur2', 'champ3=valeur3',



'champ4=valeur4']
d = dict(tuple(p.split('=')) for p in s2)
print d
{'champ4': 'valeur4', 'champ1': 'valeur1', 'champ3': 'valeur3',



'champ2': 'valeur2'}



kib
Le #682868
Salut,

sinon, tu peux toujours utiliser des groupes nommés, c'est bien pratique
(ici, valeur est définie comme étant tout ce qui se trouve entre "=" et
le prochain "&", càd qu'elle n'est pas greedy (gourmande), d'où le point
d'interrogation dans '.*?').

#-----------------------------------------------------------------
import re

test = """test?champ1=valeur1&champ2=valeur2&champ3=valeur3&champ4=valeur4
test?champ1=valeur1&champ2=valeur2&champ4=valeur4
"""

rech = re.compile(r"champ[12][=](?P<valeur>.*?)&")

for el in rech.finditer(test) :
print el.group('valeur')
#-----------------------------------------------------------------

Je te conseille d'utilise kodos pour les regexps, c'est un très bon outil.
Méta-MCI \(MVP\)
Le #682658
Bonsoir !

Je me pose une question (tordue ?) :
Champ1 peut-il contenir la valeur suivante :
&champ2=x&
?

Bon, Ok ; exit()...

Michel Claveau
Bruno Desthuilliers
Le #682656
Bonsoir !
Je me pose une question (tordue ?) : Champ1 peut-il contenir la valeur
suivante : &champ2=x&
?


Si la chaine est une requête HTTP (avoue que ça y ressemble beaucoup
!-), ce n'est pas possible. Par contre, tu peux avoir:

champ2=valeur1&champ2=valeur2&champ2=valeur3

Thoma
Le #682653
Bonsoir,

J'ai découvert les expressions régulières récemment.

Aujourd'hui, j'essaye de les utiliser pour extraire deux champs :

Les deux lignes suivantes sont :

test?champ1=valeur1&champ2=valeur2&champ3=valeur3&champ4=valeur4
test?champ1=valeur1&champ2=valeur2&champ4=valeur4

et je veux extraire "valeur1" et "valeur2".

J'ai crée l'expression suivante :

champ1=(.*)&champ2=(.*)&

Résultat : je récupère bien "valeur1". Tout se complique avec le second
groupe puisque je me retrouve avec "valeur2&champ3=valeur3". Je
m'attendais à n'avoir que "valeur2".

En cherchant sur la toile, j'ai trouvé une histoire de 'greedy' et
'ungreedy'.

Malheureusement, mes essais ne m'ont pas permis de trouver la bonne
expression me permettant d'extraire "valeur1" et "valeur2".

Si quelqu'un a une idée (et surtout une explication), je suis preneur.

D'avance merci

Thoma


Bonsoir,

Je vous remerci tous de l'aide que vous m'avez apporté.
Maintenant, je comprends l'utilisation du ungreedy (je le plaçais au
mauvais endroit lors de mes multiples essais).

Thoma

Publicité
Poster une réponse
Anonyme