[RESOLU] Problème avec preg_replace

Petit nouveau ! | 6 Messages

12 août 2022, 08:15

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 !!!

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

12 août 2022, 10:18

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
Quand tout le reste a échoué, lisez le mode d'emploi...

Petit nouveau ! | 6 Messages

12 août 2022, 11:02

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.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

12 août 2022, 11:09

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)
Quand tout le reste a échoué, lisez le mode d'emploi...

Petit nouveau ! | 6 Messages

12 août 2022, 11:16

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.

Petit nouveau ! | 6 Messages

12 août 2022, 11:46

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.

Petit nouveau ! | 6 Messages

12 août 2022, 11:52

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.

Petit nouveau ! | 6 Messages

12 août 2022, 12:15

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.