Page 1 sur 1

Problème avec preg_replace

Posté : 12 août 2022, 08:15
par julienlepage
Bonjour !

J'ai un problème tout bête sur lequel je m'arrache les cheveux !
J'ai une variable, $e, qui contient
<a class="machin" href="/truc bidule">Truc Bidule</a>
Pour que mon code soit plus propre, je voudrais remplacer les éventuelles espaces de mon href par %20.
J'ai donc tenté ceci :
$e = preg_replace('href="(*)"', str_replace(' ', '%20', 'href="$1"'), $e);
Et ça ne me renvoie rien du tout.
Quel est le souci ?

Merci d'avance !!!

Re: Problème avec preg_replace

Posté : 12 août 2022, 10:18
par @rthur
Normal, preg_replace() ne s'utilise pas comme ça : le 1er paramètre doit être un pattern regex et la tienne c'est n'importe quoi, et le 2ème paramètre doit être ce par quoi tu remplaces et non pas une fonction.
https://php.net/preg_replace
Pour ta regex, utilise https://regex101.com pour la construire/tester, ton objectif n'est pas de récupérer tout le contenu de ton lien mais uniquement les espaces, que tu vas ensuite remplacer.


Une autre approche, plus complexe mais techniquement meilleure serait d'utiliser la fonction preg_replace_callback() justement pour pouvoir passer une fonction en 2ème argument, et de ne pas faire juste un str_replace() sur les espaces, mais d'utiliser la fonction PHP qui permet justement d'encoder tous les caractères spéciaux des url à savoir urlencode()
https://php.net/preg_replace_callback
https://php.net/urlencode

Re: Problème avec preg_replace

Posté : 12 août 2022, 11:02
par julienlepage
Merci pour la réponse ! On avance !

J'ai essayé ceci :
$e = preg_replace_callback($pattern, function ($matches) { return urlencode($matches[0]); }, $e);
Et ça fonctionne. Il y a juste mon $pattern qui déconne. Comme tu dis :
la tienne c'est n'importe quoi
Et pourtant, en essayant sur Regex101, avec :
href="(.*)"
J'obtiens bien ce que je veux. Je ne comprends pas ce qui pose problème.

Re: Problème avec preg_replace

Posté : 12 août 2022, 11:09
par @rthur
Pour un pattern regex, il te faut un délimiteur et éventuellement des options.
Par défaut regex101 utilises les options "gm" (global et multiline) et le slash en délimiteur (regarde là où tu as mis ton pattern).
En l'occurence, je te déconseille d'utiliser le slash car ça pourrait interférer avec ton pattern, je te recommande d'utiliser le backtick ` (AltGr + 7)

Re: Problème avec preg_replace

Posté : 12 août 2022, 11:16
par julienlepage
Oui, je me suis rendu compte juste après avoir posté que j'avais oublié le délimiteur.
Que ce soit avec / ou avec `, ça ne fonctionne pas. Enfin ça fonctionne très bien sur regex101, mais pas en conditions réelles.

Re: Problème avec preg_replace

Posté : 12 août 2022, 11:46
par julienlepage
Après un nouveau test sur regex101, c'est href=".*?" qui fonctionne le mieux (avec ` et gm).
Mais la fonction :
$e = preg_replace_callback('`href=".*?"', function ($matches) { return urlencode($matches[0]); }, $e);
Ne fonctionne toujours pas. Et c'est bien le pattern regex qui pose problème.

Re: Problème avec preg_replace

Posté : 12 août 2022, 11:52
par julienlepage
Note :
$e = preg_replace_callback('`href=".*?"`gm', function ($matches) { return urlencode($matches[0]); }, $e);
$e = preg_replace_callback('`href=".*?"', function ($matches) { return urlencode($matches[0]); }, $e);
$e = preg_replace_callback(`href=".*?"`, function ($matches) { return urlencode($matches[0]); }, $e);
$e = preg_replace_callback('href=".*?"', function ($matches) { return urlencode($matches[0]); }, $e);
Ne fonctionnent pas non plus.

Re: Problème avec preg_replace

Posté : 12 août 2022, 12:15
par julienlepage
Problème résolu !
La bonne réponse était :
$e = preg_replace_callback('/href="[^"]*"/i', function ($matches) { return str_replace(' ', '+', $matches[0]); }, $e);
J'ai laissé tomber la fonction urlencode qui me faisait n'importe quoi. Quand je passe en gm, ça ne fonctionne plus, bizarrement.