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} /.