Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Aide avec les regex

3 réponses
Avatar
Patrick Drouin
Bonjour,

J'ai un petit problème avec les regex de PHP. Voici le code :

<?php

$str="aabcc";
$pattern="/((a+)b?(c+))/";

preg_match_all($pattern,$str,$matches);
print_r($matches);

?>

Ce que je m'attendrais à avoir en retour est :
a
aa
c
cc
abc
aabc
abcc
aabbcc

Mais j'obtiens ça :
Array
(
[0] => Array
(
[0] => aabcc
)

[1] => Array
(
[0] => aabcc
)

[2] => Array
(
[0] => aa
)

[3] => Array
(
[0] => cc
)

)


Je n'ai donc que les chaînes maximales...

Des idées?
Patrick

3 réponses

Avatar
Olivier Miakinen

J'ai un petit problème avec les regex de PHP. Voici le code :

<?php

$str="aabcc";
$pattern="/((a+)b?(c+))/";

preg_match_all($pattern,$str,$matches);
print_r($matches);

?>

Ce que je m'attendrais à avoir en retour est :
a
aa
c
cc
abc
aabc
abcc
aabbcc


Ah non ! Les seules chaînes qui respectent ton masque sont les
suivantes :
abc
aabc
abcc
aabcc

Éventuellement, si ton masque avait été /((a*)b?(c*))/ au lieu de
/((a+)b?(c+))/, tu aurais pu espérer d'autres résultats. Mais tu te
heurtes au même problème que CrazyCat. C'est même rigolo que vous
ayez posé vos questions au même moment, modulo l'heure de modération.

Mais j'obtiens ça :
Array
(
[0] => Array
(
[0] => aabcc
)

[1] => Array
(
[0] => aabcc
)

[2] => Array
(
[0] => aa
)

[3] => Array
(
[0] => cc
)

)


Eh oui, c'est tout à fait normal.

Je n'ai donc que les chaînes maximales...


Tu n'as que *la* chaîne maximale (et les trois sous-chaînes
correspondant aux trois paires de parenthèses capturantes).
Tu pourrais obtenir la sous-chaîne minimale à la place avec
l'option U — et encore pas exactement : tu devrais obtenir
aabc — mais tu ne pourras jamais obtenir tous les choix
possibles en une seule requête.

Avatar
Moi
On 17 déc, 17:24, Olivier Miakinen <om+ wrote:

Ah non ! Les seules chaînes qui respectent ton masque sont les
suivantes :
abc
aabc
abcc
aabcc

Éventuellement, si ton masque avait été /((a*)b?(c*))/ au lieu de
/((a+)b?(c+))/, tu aurais pu espérer d'autres résultats. Mais tu te
heurtes au même problème que CrazyCat. C'est même rigolo que vous
ayez posé vos questions au même moment, modulo l'heure de modération.


C'est vrai que c'est rigolo, le problème est semblable... Je ne savais
surtout pas que le groupe était modéré! Une bonne chose. Enfin, je ne
comprends toujours pas pourquoi (a+) n'est pas capturé et pourquoi ça
ne me donne pas les a, aa, aaa, ... Ce sous-masque en lui-même est
capturant et indépendant des deux autres non? J'ai dû louper un truc.

Tu pourrais obtenir la sous-chaîne minimale à la place avec
l'option U -- et encore pas exactement : tu devrais obtenir
aabc -- mais tu ne pourras jamais obtenir tous les choix
possibles en une seule requête.


Voici la sortie (alors là, je n'y comprends plus rien. Ça n'a rien à
voir avec Perl!) :
Array
(
[0] => Array
(
[0] => aabc
)

[1] => Array
(
[0] => aabc
)

[2] => Array
(
[0] => aa
)

[3] => Array
(
[0] => c
)

)

Merci pour l'aide, c'est TRÈS apprécié.
Patrick

Avatar
Olivier Miakinen

[...] je ne
comprends toujours pas pourquoi (a+) n'est pas capturé et pourquoi ça
ne me donne pas les a, aa, aaa, ...


Mais il *est* capturé ! Tu l'as dans $matches[2][0] qui contient "aa".

Ce sous-masque en lui-même est capturant


Oui.

et indépendant des deux autres non?


Non. Il faut que l'expression complète soit acceptée, et seulement alors
tu as dans $matches[2] l'ensemble des résultats pour (a+), en l'occur-
rence un seul ici. Essaye avec "aabcc aaacc abccc bc ab" pour en obtenir
d'autres (pour cet exemple : "aa", "aaa", "a").

Voici la sortie (alors là, je n'y comprends plus rien. Ça n'a rien à
voir avec Perl!) :


[ je traduis le résultat que tu indiques : ]

Masque complet ((a+)b?(c+)) :
aabc
Contenu de la première parenthèse (a+)b?(c+) :
aabc
Contenu de la deuxième parenthèse a+ :
aa
Contenu de la troisième parenthèse c+ :
c


C'est bien la sortie attendue. Du peu que je connais de Perl, il ne t'en
retourne pas d'autres — mais je veux bien être détrompé.