J'ai essayé d'utiliser l'expression régulière (php) pour faire correspondre les chiffres romains de fin. Pour simplifier, considérez l'exemple ci-dessous:
$str="Olympic III"; preg_match("#^(.*)(III|II|I)$#",$str,$rep); print_r($rep);
Cela ne correspondra qu'à un seul "I". La bonne réponse est pour moi d'utiliser le modificateur "U" ungreedy. Mais pourquoi? L'expression régulière n'utilise-t-elle pas l'ordre que j'ai fourni (essayez d'abord "III" avant d'essayer "II" ou "I")?
3 Réponses :
. * correspond au plus grand nombre de caractères avant (III | II | I) et (III | II | I) ne peut correspondre qu'à un seul caractère, vous pouvez utiliser cet exemple de regex ^ (. *) \ s (I +) $ p >
Essayez ceci:
$str="Olympic III"; preg_match("#^(.*)\s(I+)$#",$str,$rep); print_r($rep);
\ s
avant (I +)
ou (III | II | I)
correspond à un seul espace et cela résout votre problème car il force l'expression rationnelle à correspondre à (. *)
uniquement au début de la partie intéressante.
Voyons d'abord ce que fait le \ U
. Cela rend les quantificateurs (dans votre cas, le *
dans le premier groupe de capture) paresseux par défaut.
Votre expression régulière équivaut à (. *?) (III | II | I)
sans l'indicateur Ungreedy, qui correspond comme vous vous y attendez.
Avec (. *) (III | II | I)
ce que vous demandez réellement au moteur d'expression régulière est d'utiliser les quantificateurs avec gourmandise, c'est-à-dire de faire correspondre tout ce qu'ils peuvent aussi longtemps qu'ils le peuvent. Puisque votre alternance permet d'accepter soit III
, II
, ou I
, le premier groupe de capture, puisqu'il agit avec gourmandise, consomme le plus , et laisse la plus petite partie pour le deuxième groupe qui contient l'alternance.
Essayez
/ I {1,3} /
.