Bonjour a tous,

Une chaine de caractères est constituée de trois élements separés par des underscores:
- le premier (lettres et chiffres)
- le milieu (lettre, chiffre et underscore)
- le dernier (lettres et chiffres)

Le dernier element est optionel.

Note : je dois pouvoir acceder a mes groupes par leur nom et non pas par leur index.

Exemples :

Chaine : abc_def
premier : abc
milieu : def
dernier : inexistant

Chaine : abc_def_xyz
premier : abc
milieu: def
dernier: xyz

Chaine : abc_def_ghi_jkl_xyz
premier : abc
milieu : def_ghi_jkl
dernier : xyz


Je n'arrive pas écrire d'expression regulière permettant de matcher mes chaines... Je suis parti sur deux pistes :

Groupe optionel
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
(?P<premier>[a-z]+)_(?P<milieu>\w+)(_(?P<dernier>[a-z]+))?
Mais le second groupe matche jusqu'a la fin de la chaine :

Chaine : abc_def_ghi_jkl_xyz
premier : abc
milieu : def_ghi_jkl_xyz
dernier : vide


La seconde piste est l'utilisation du '|' :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
(?P<premier>[a-z]+)_(?P<milieu>\w+)_(?P<dernier>[a-z]+)|(?P<premier>[a-z]+)_(?P<milieu>\w+)
Cette expression est invalide : les groupes premier et milieu sont déclarés deux fois. Je pensais alors pouvoir ecrire une expression qui réutilise les groupes matchés dans la première partie de l'expression :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
(?P<premier>[a-z]+)_(?P<milieu>\w+)_(?P<dernier>[a-z]+)|(?P=premier)_(?P=milieu)
L'expression est valide, mais refuse de matcher les chaines avec juste un premier et un milieu comme abc_def.

Avez-vous une idée pour resoudre mon problème ? Merci beaucoup !