1
votes

correspondance d'expression régulière se terminant par III ou II ou I (php)

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")?


1 commentaires

Essayez / I {1,3} / .


3 Réponses :


0
votes

. * 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 +) $


0 commentaires

0
votes

Essayez ceci:

$str="Olympic III";
preg_match("#^(.*)\s(I+)$#",$str,$rep);
print_r($rep);

PHP Sandbox

\ 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.


0 commentaires

1
votes

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.


0 commentaires