Expression régulière en PHP

HTML5, CSS3, Javascript, support des mobiles... Que penser de votre site ? Vous manquez d'informations pour la construction d'un site qui puisse s'afficher correctement partout ? C'est un problème simple, un peu complexe ? Venez ici !
Benoit
Administrateur
Messages : 4894
Inscription : 19 juil. 2003, 10:59

Expression régulière en PHP

Message 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...
chBok
Iguane
Messages : 991
Inscription : 17 oct. 2003, 19:17

Message 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 :idea: )
Benoit
Administrateur
Messages : 4894
Inscription : 19 juil. 2003, 10:59

Message 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à :)
chBok
Iguane
Messages : 991
Inscription : 17 oct. 2003, 19:17

Message 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é.
Benoit
Administrateur
Messages : 4894
Inscription : 19 juil. 2003, 10:59

Message 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);
LezeuS
Lézard vert
Messages : 158
Inscription : 29 juil. 2003, 19:00

Message 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.
Répondre

Qui est en ligne ?

Utilisateurs parcourant ce forum : Semrush [Bot] et 2 invités