Page 1 sur 1
Expression régulière en PHP
Publié : 17 janv. 2004, 17:30
par Benoit
Bonjour, cette fois c'est moi qui ai besoin d'aide
Je suis occupé à améliorer le script d'affichage de la FAQ pour que les liens de phpFAQTory puissent fonctionner. Ils utilisent une syntaxe
assez particulière qu'on peut résumer ainsi :
Code : Tout sélectionner
<LINK>Intitulé|URL</LINK>
<LINK>Intitulé|CxQy</LINK>
<LINK>Intitulé|Cx</LINK>
'x' indique un numéro de chapitre et 'y' un numéro de question.
Je dois transformer ça en de vrais liens, c'est-à-dire respectivement :
Code : Tout sélectionner
<a href="URL">Intitulé</a>
<a href="url/de/la/faq/?chapitre=x">Intitulé</a>
<a href="url/de/la/faq/?chapitre=x#qy">Intitulé</a>
Le code qui existe à l'intérieur de phpFAQTory fait ça en une trentaine de lignes que je n'ai pas envie de recopier parce que je *sais* que c'est possible avec une ou deux expressions régulières. Seulement c'est un peu compliqué pour moi, j'arrive bien à adapter quelques expressions régulières existantes avec beaucoup de coups d'yeux à la doc et de patience mais manifestement pas à en écrire moi-même.
Pour l'instant j'ai ça pour essayer de traiter le second cas :
Code : Tout sélectionner
$reponse = preg_replace( "/<LINK>([^~])\|([^~]+)<\/LINK>/i", "<a href=\"index.php?reponse_id=$2\">$1</a>", $reponse );
... qui ne fonctionne absolument pas
(un htmlentities a déjà été passé dessus, d'où les < et >)
Bref, si quelqu'un peut m'aider un peu...
Publié : 17 janv. 2004, 18:27
par chBok
Rapidement, j'ai regardé en utilisant la fonction
eregi
Code : Tout sélectionner
$txt[] = "<LINK>Intitulé|URL</LINK>";
$txt[] = "<LINK>Intitulé|CxQy</LINK>";
$txt[] = "<LINK>Intitulé|Cx</LINK>";
for($i=0; $i<3; $i++) {
eregi( "<LINK>([^\|]+)\|((C(.+)Q(.+))|(C(.+))|(.+))</LINK>", $txt[$i], $out);
print_r($out); echo "<br />";
}
donne
Code : Tout sélectionner
Array ( [0] => Intitulé|URL [1] => Intitulé [2] => URL [3] => [4] => [5] => [6] => [7] => [8] => URL [9] => )
Array ( [0] => Intitulé|CxQy [1] => Intitulé [2] => CxQy [3] => CxQy [4] => x [5] => y [6] => [7] => [8] => [9] => )
Array ( [0] => Intitulé|Cx [1] => Intitulé [2] => Cx [3] => [4] => [5] => [6] => Cx [7] => x [8] => [9] => )
Il faut tester $out et construire le lien :
- $out[4] non vide x=$out[4] et y=$out[5]
- $out[7] non vide x=$out[7]
- $out[8] non vide url=$out[8]
(Maintenant, on peut faire peut être plus simple

)
Publié : 17 janv. 2004, 18:48
par Benoit
Pour pouvoir mettre ça dans un ereg_replace, il faudrait que l'ordre des paramètres soit toujours le même (cad que x et y soient dans la même case du tableau).
Il est dit que les expressions ereg sont plus lentes que les preg mais j'ai moins de mal à les comprendre donc je vais sans doute utiliser ça
Une différente pour le premier cas (URL), et en positionnant les parenthèses différemment je devrais pouvoir traiter les deux autres en une fois. J'essaierai ça demain, à moins que quelqu'un trouve mieux d'ici-là

Publié : 17 janv. 2004, 22:02
par chBok
J'ai regardé le code source de phpfactory, notamment la fonction question_parser() et c'est vrai qu'elle pourrait être optimisée.
Si tu préfères les preg, comme il y a 3 cas pour la restitution d'un lien, on peut utiliser des tableaux comme ceci :
Code : Tout sélectionner
$txt="<LINK>Intitulé|C12Q5</LINK>"; //exemple
$patterns = array(
"/<LINK>([^|]+)\|C(\d+)Q(\d+)<\/LINK>/i",
"/<LINK>([^|]+)\|C(\d+)<\/LINK>/i",
"/<LINK>([^|]+)\|([^<]+)<\/LINK>/i" );
$changes = array(
'<a href="url/page.html?chapitre=$2#$3">$1</a>',
'<a href="url/page.html?chapitre=$2">$1</a>',
'<a href="$2">$1</a>' );
echo "<p>".preg_replace($patterns, $changes, $txt)."</p>";
(il faudrait remplacer les < et > par leurs codes html)
Ca devrait fonctionner, enfin oui, pour les quelques tests que j'ai effectué.
Publié : 17 janv. 2004, 23:03
par Benoit
Wow merci beaucoup
Ça fonctionne partout sauf pour les deux derniers liens de la question 4.2. Il y a sans doute quelque chose de spécial dedans, peut-être un retour à la ligne je demanderai à Snap ou à LezeuS de jetter un coup d'œil.
Pour les curieux le code final est
Code : Tout sélectionner
$patterns = array(
"/<LINK>([^|]+)\|C(\d+)Q(\d+)<\/LINK>/i",
"/<LINK>([^|]+)\|C(\d+)<\/LINK>/i",
"/<LINK>([^|]+)\|([^<]+)<\/LINK>/i" );
$changes = array(
'<a href="index.php?voir=3#n$2.$3">$1</a>',
'<a href="index.php?voir=2#n$2">$1</a>',
'<a href="$2">$1</a>' );
$reponse = preg_replace($patterns, $changes, $reponse);
Publié : 18 janv. 2004, 13:07
par LezeuS
J'ai répondu sur la ml. Il faut un retour à la ligne juste avant un LINK pour que ce soit pris en compte sur la page d'affichage de la FAQ, alors que sur phpfactory, il n'y a pas ce probleme.