Comprendre tout les jours un peu plus le preg_replace

Comprendre tout les jours un peu plus le preg_replace - PHP - Programmation

Marsh Posté le 03-12-2008 à 15:33:16    

Mesdames et Messieurs bien le bonjour
 
j'aimerais comprendre le fonctionnement d'une expression régulière me permettant de mettre en forme une chaîne toute pourrie en un beau div html.
 
voici ma chaîne :  
ref_player="27351" num_position="" num_played="1" num_time="0" num_goal="0" txt_url="Ligue 1/player/27351" date_year="20,5"
 
ceci est bien sur imbitable sans une belle mise en forme et je voudrais donc le passer dans une moulinette du type :  
 

$pattern = "ref_player="([0-9])" num_position="" num_played="([0-9])" num_time="([0-9])" num_goal="([0-9])" txt_url="(.*?)" date_year="([0-9][,])"";
$replace = "
<div>
player id = $1<br />
matchs joués = $2<br />
temps de jeu = $3<br />
nombre de but = $4<br />
url = $5<br />
age : $6
</div>
";
$string  = preg_replace( $pattern, $replace, $string );
echo $string;


 
Si vous pouvez m'aider à mieux comprendre ce que je dois mettre pour que ça fonctionne, ça serais super.
 
Bonne continuation.

Reply

Marsh Posté le 03-12-2008 à 15:33:16   

Reply

Marsh Posté le 03-12-2008 à 15:39:24    

[0-9] c'est un seul chiffre, déjà.
 
Tu veux [0-9]* ou [0-9]+.
 
Pour date_year pareil avant la virgule, et t'oublies de matcher après la virgule...


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 03-12-2008 à 16:04:14    

Quel est la différence profonde entre [0-9]* et [0-9]+ ?
 
Par rapport à  la virgule... En fait, le chiffre n'a pas forcément de virgule... ça peut être '20,9' ou '20', tout court.

Reply

Marsh Posté le 03-12-2008 à 16:06:00    

http://www.expreg.com/
Bonne lecture.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 03-12-2008 à 16:36:43    

Merci skeye !!
 
après lecture, je met donc à jour ma ligne de commande :  
 
ref_player="([0-9]+)" num_position="" num_played="([0-9]+)" num_time="([0-9]+)" num_goal="([0-9]+)" txt_url="(.*?)" date_year="([0-9|0-9,0-9]+)"
 
Je sèche encore sur le 20,1 ou 20...
 
de plus, je me demande si je dois échapper les " qui sont dans la chaîne ?

Message cité 1 fois
Message édité par xkamui le 03-12-2008 à 16:37:50
Reply

Marsh Posté le 03-12-2008 à 17:48:05    

xkamui a écrit :

de plus, je me demande si je dois échapper les " qui sont dans la chaîne ?


Oui, par un \

Code :
  1. $pattern = ref_player="([0-9]+)" num_position=""

=>

Code :
  1. $pattern = "ref_player=\"([0-9]+)\" num_position=\"\" [...]"


 
Pour ton pb de date_year si tu veux accepter les entrées suivantes : 20,1 ou 20 ou 0,1 utilise le pattern suivant :

Code :
  1. ([0-9]+(\,[0-9]+)?)


Qui correspond à : "un ou plusieurs chiffres et éventuellement une virgule suivie d'un ou plusieurs chiffres"


---------------
By bob.
Reply

Marsh Posté le 03-12-2008 à 18:24:34    

Super, merci beaucoup superbob56 !!
 
voici donc ce que j'ai maintenant :  
 
  $pattern = "ref_player=\"([0-9]+)\" num_position=\"\" num_played=\"([0-9]+)\" num_time=\"([0-9]+)\" num_goal=\"([0-9]+)\" txt_url=\"(.*?)\" date_year=\"([0-9]+(\,[0-9]+)?)\"";
  $replace = "<div><span class=\"toto\">$1</span></div>";
  echo "hello" . preg_replace( $pattern, $replace, $string ) . "<br />\r\n";
 
j'ai pas mon div, mais j'ai bien mes 'hello' qui s'affichent...
 
Je ne vois pas pourquoi, car ça à l'air ok là, non ?

Reply

Marsh Posté le 03-12-2008 à 19:22:09    

Est-ce vraiment top une telle regexp pour ce genre de cas ? Genre suffit que deux attributs switchent de place et ça pète

Reply

Marsh Posté le 03-12-2008 à 19:37:41    

FlorentG a écrit :

Est-ce vraiment top une telle regexp pour ce genre de cas ? Genre suffit que deux attributs switchent de place et ça pète


 
Bel effort, maintenant il va te demander de lui écrire la version qui résout ce problème :D


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 03-12-2008 à 19:38:16    

Oui, FlorentG, mais disons deux choses
 
1- Je ne suis pas vraiment responsable de la création du 'pattern' et donc si deux attribut switchent, je n'y serait pour rien en cas de non fonctionnement ultérieur
 
2- Même si on part de l'hypothèse (insensée, je le conçoit) que rien ne changera jamais, l'exmple ne fonctionne pas...
 
Point positif, j'ai appris un peu plus sur les expressions régulières :p
 
Donc, si quelqu'un voit pourquoi ça fonctionne toujours pas ?

Reply

Marsh Posté le 03-12-2008 à 19:38:16   

Reply

Marsh Posté le 03-12-2008 à 19:38:38    

ah ah ah esox_ch => même pas en fait :D

Reply

Marsh Posté le 03-12-2008 à 20:11:44    

xkamui a écrit :


  $pattern = "ref_player=\"([0-9]+)\" num_position=\"\" num_played=\"([0-9]+)\" num_time=\"([0-9]+)\" num_goal=\"([0-9]+)\" txt_url=\"(.*?)\" date_year=\"([0-9]+(\,[0-9]+)?)\"";
  $replace = "<div><span class=\"toto\">$1</span></div>";
  echo "hello" . preg_replace( $pattern, $replace, $string ) . "<br />\r\n";
 
j'ai pas mon div, mais j'ai bien mes 'hello' qui s'affichent...
 
Je ne vois pas pourquoi, car ça à l'air ok là, non ?


Pour être sûr, affiche les trois chaines pattern, replace et string pour vérifier que l'échappement se fait bien et que rien n'a été oublié
Et puis essaye progressivement, juste la partie ref_player="([0-9]+)" pour commencer et continue petit à petit.


---------------
By bob.
Reply

Marsh Posté le 03-12-2008 à 20:13:25    

Sinon nettement plus simple/propre/efficace/ tu mets ça dans une balise, genre :

Code :
  1. <player ref_player="27351" num_position="" num_played="1" num_time="0" num_goal="0" txt_url="Ligue 1/player/27351" date_year="20,5" />


 
Pis t'utilises http://simplehtmldom.sourceforge.net/ pour parser les attributs.

Message cité 1 fois
Message édité par sielfried le 03-12-2008 à 20:13:39

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 03-12-2008 à 21:58:31    

sielfried a écrit :

Sinon nettement plus simple/propre/efficace/ tu mets ça dans une balise, genre :

Code :
  1. <player ref_player="27351" num_position="" num_played="1" num_time="0" num_goal="0" txt_url="Ligue 1/player/27351" date_year="20,5" />


 
Pis t'utilises http://simplehtmldom.sourceforge.net/ pour parser les attributs.


euh là c'est plus du tout du html que tu génères, hein...:o


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 11:30:57    

skeye a écrit :


euh là c'est plus du tout du html que tu génères, hein...:o


 
C'est du XML valide. Le truc le gère aussi, même quand y a pas d'entête ni rien.


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 11:38:07    

sielfried a écrit :

 

C'est du XML valide. Le truc le gère aussi, même quand y a pas d'entête ni rien.

 

oui, mais les navigateurs ne sont pas censés savoir quoi en faire au milieu d'une page html, et peuvent te faire péter la page à la gueule s'ils en ont l'envie.[:el g]

Message cité 1 fois
Message édité par skeye le 04-12-2008 à 11:38:17

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 11:56:24    

skeye a écrit :


 
oui, mais les navigateurs ne sont pas censés savoir quoi en faire au milieu d'une page html, et peuvent te faire péter la page à la gueule s'ils en ont l'envie.[:el g]


 
Nan mais il transforme ça dans son PHP en mémoire pour pouvoir récupérer ses attributs proprement et créer son div, personne n'a parlé d'afficher ça tel quel. [:petrus75]

Message cité 1 fois
Message édité par sielfried le 04-12-2008 à 11:57:26

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 12:44:07    

sielfried a écrit :

Nan mais il transforme ça dans son PHP en mémoire pour pouvoir récupérer ses attributs proprement et créer son div, personne n'a parlé d'afficher ça tel quel. [:petrus75]

 

mais bien sûr, il va générer du html non conforme en mémoire pour pouvoir le re-parser en php sans jamais l'afficher. Va falloir que tu m'expliques ce que tu fumes toi hein...[:el g]

Message cité 1 fois
Message édité par skeye le 04-12-2008 à 12:44:34

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 14:07:29    

skeye a écrit :


 
mais bien sûr, il va générer du html non conforme en mémoire pour pouvoir le re-parser en php sans jamais l'afficher. Va falloir que tu m'expliques ce que tu fumes toi hein...[:el g]


 
Mais c'est pas du HTML robert, on parle de XML là, toi me lire (ou la doc du truc sinon, au choix) ? [:petrus75]  
 
Il a sa chaîne (je sais pas d'où il la sort d'ailleurs, mais on s'en cague un peu), il s'aperçoit qu'elle ressemble vachement à une liste d'attributs XML, donc il transforme ça en tag XML, et il parse avec un vrai parseur de XML fait pour ça. Et il a la valeur de ses attributs sans aucune regexp, sans qu'un \" ou qu'un ordre différent des attributs vienne foutre le bordel. Ensuite il crée son div dans sa vue comme un grand.
 
J'peux te faire un dessin, si tu préfères.


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 14:28:50    

sielfried a écrit :


 
Mais c'est pas du HTML robert, on parle de XML là, toi me lire (ou la doc du truc sinon, au choix) ? [:petrus75]  
 
Il a sa chaîne (je sais pas d'où il la sort d'ailleurs, mais on s'en cague un peu), il s'aperçoit qu'elle ressemble vachement à une liste d'attributs XML, donc il transforme ça en tag XML, et il parse avec un vrai parseur de XML fait pour ça. Et il a la valeur de ses attributs sans aucune regexp, sans qu'un \" ou qu'un ordre différent des attributs vienne foutre le bordel. Ensuite il crée son div dans sa vue comme un grand.
 
J'peux te faire un dessin, si tu préfères.


1) Je m'appelle pas robert.
2) Tu es le seul à parler de xml, là. Lui il a une chaine de caractères, il veut en extraire des valeurs avec une regexp. Ta solution c'est d'ajouter une lib supplémentaire et de bidouiller pour lui passer des infos au format qu'elle attend? Et tu appelles ça "simple/propre/efficace"? C'est une blague?


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 14:38:47    

skeye a écrit :


2) Tu es le seul à parler de xml, là. Lui il a une chaine de caractères, il veut en extraire des valeurs avec une regexp.  


 
C'est pas parce qu'il nous parle de regexp que c'est la bonne solution. En l'occurence, pour parser un truc qui ressemble de près ou de loin à de l'XML, c'est relativement merdique. :o  
 

Citation :

Ta solution c'est d'ajouter une lib supplémentaire et de bidouiller pour lui passer des infos au format qu'elle attend? Et tu appelles ça "simple/propre/efficace"? C'est une blague?


 
La bidouille, c'est d'utiliser des regexp pour extraire des infos d'un format qu'on peut parser avec un vrai parseur fait pour ça. [:petrus75]  
 
La bibliothèque est légère, peut lui servir dans pleins d'autres cas similaires, lui permet de ne pas se prendre le chou avec des choses genre un \" au milieu de ses attributs (ça doit être joli à gérer en regexp) ou leur ordre (sympa aussi), tout en produisant du code environ 52 fois plus lisible et certainement au moins aussi performant.

Message cité 1 fois
Message édité par sielfried le 04-12-2008 à 14:39:38

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 14:44:07    

sielfried a écrit :

C'est pas parce qu'il nous parle de regexp que c'est la bonne solution. En l'occurence, pour parser un truc qui ressemble de près ou de loin à de l'XML, c'est relativement merdique. :o


 
Tu crois qu'elle fait comment ta lib?[:moule_bite]
Allez, je l'ai même récupérée pour regarder, c'est cadeau :
 

Code :
  1. protected function match($exp, $pattern, $value) {
  2.        $check = true;
  3.        switch ($exp) {
  4.            case '=':
  5.                $check = ($value===$pattern) ? true : false; break;
  6.            case '!=':
  7.                $check = ($value!==$pattern) ? true : false; break;
  8.            case '^=':
  9.                $check = (preg_match("/^".preg_quote($pattern,'/')."/", $value)) ? true : false; break;
  10.            case '$=':
  11.                $check = (preg_match("/".preg_quote($pattern,'/')."$/", $value)) ? true : false; break;
  12.            case '*=':
  13.                $check = (preg_match("/".preg_quote($pattern,'/')."/i", $value)) ? true : false; break;
  14.        }
  15.        return $check;
  16.    }
  17.  
  18. protected function parse_selector($selector_string) {
  19.        // pattern of CSS selectors, modified from mootools
  20.        $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([, ]+)/is";
  21.        preg_match_all($pattern, trim($selector_string).' ', $matches, PREG_SET_ORDER);
  22.  
  23.  
  24.  
  25.  function __construct($str=null) {
  26.        if ($str) {
  27.            if (preg_match("/^http:\/\//i",$str) || is_file($str))
  28.                $this->load_file($str);
  29.      
  30.  
  31. etc etc etc


 
C'est sûr qu'ajouter une lib non officielle consistant en une grosse classe de 900 lignes ça va être vachement plus performant que de faire exactement le bout de code dont il a besoin, tout en en profitant pour apprendre à se servir d'un outil.[:moule_bite]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 14:59:49    

Mais on s'en tamponne de son implémentation, à la bibliothèque.  [:pingouino]  [:pingouino]  
 
Elle parse proprement le truc, avec des performances parfaitement honorables, et une API python-like hyper bien foutue et qui permet d'avoir un code lisible, maintenable et adaptable, et qui se vautre pas lamentablement si t'as oublié qu'il pouvait y avoir plus d'un espace entre chaque attribut ou qu'un \" pouvait venir foutre le bazar.
 
Après si tu préfères gagner 3 centièmes de seconde pour t'amuser avec des regexp bancales et qui prennent 2 minutes à relire/adapter c'est toi qui vois.  [:petrus75]  (Ou lui, en fait.)
 
Mais vas-y fais toi plaisir et sors nous donc l'expression qui prend tous les cas en compte. [:petrus75]

Message cité 2 fois
Message édité par sielfried le 04-12-2008 à 15:01:08

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 15:03:14    

sielfried a écrit :

Mais on s'en tamponne de son implémentation, à la bibliothèque.  [:pingouino]  [:pingouino]

 

Elle parse proprement le truc, avec des performances parfaitement honorables, et une API python-like hyper bien foutue et qui permet d'avoir un code extrêmement lisible, maintenable et adaptable, et qui se vautre pas lamentablement si t'as oublié qu'il pouvait y avoir plus d'un espace entre chaque attribut ou qu'un \" pouvait venir foutre le bazar.

 

Après si tu préfères gagner 3 centièmes de seconde pour t'amuser avec des regexp bancales et qui prennent 2 minutes à relire/adapter c'est toi qui vois.  [:petrus75]

 

Ou lui, en fait.

 

(Mais j'attends de voir la beauté de la regexp qui prendra tous les cas en compte, tiens...)

 

Le seul truc que tu oublies, c'est qu'il a pas du xml, et encore moins 'nimporte-quel xml en entrée. Il n'a pas tous les cas à gérer, il a juste ceux qui l'intéressent. Et ta lib n'offre absolument aucune garantie de fonctionner, c'est un projet sourceforge d'un mec dans son coin, le jour où ça t'explose à la gueule sans prévenir parce-que le mec a pas prévu un cas tu l'as dans le cul.
Bref.


Message édité par skeye le 04-12-2008 à 15:03:42

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 15:18:39    

skeye a écrit :


Le seul truc que tu oublies, c'est qu'il a pas du xml, et encore moins 'nimporte-quel xml en entrée. Il n'a pas tous les cas à gérer, il a juste ceux qui l'intéressent.


 
$string = '<player ' . $string . ' />'; ça me paraît pas dramatique comme truc à avoir à faire avant de parser. Après, ça dépend d'où vient la chaîne, y a certainement un meilleur endroit pour le faire.
 

Citation :


 Et ta lib n'offre absolument aucune garantie de fonctionner, c'est un projet sourceforge d'un mec dans son coin, le jour où ça t'explose à la gueule sans prévenir parce-que le mec a pas prévu un cas tu l'as dans le cul.
Bref.


 
Bah rien ne t'empêche d'aller la modifier, le code est clair et loin d'être sorcier (et de prévenir l'auteur d'ailleurs, c'est un projet actif, la dernière release doit dater de deux mois max :spamafote: edit: ouais voilà, 25 octobre).

Message cité 1 fois
Message édité par sielfried le 04-12-2008 à 15:20:15

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 15:20:11    

sielfried a écrit :

Bah rien ne t'empêche d'aller la modifier, le code est clair et loin d'être sorcier (et de prévenir l'auteur d'ailleurs, c'est un projet actif, la dernière release doit dater de deux mois max :spamafote:).


Ah oui c'est vrai c'est tout de suite vachement plus simple que de faire le truc adapté à son problème.[:pingouino]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 15:26:56    

skeye a écrit :


Ah oui c'est vrai c'est tout de suite vachement plus simple que de faire le truc adapté à son problème.[:pingouino]


 
Donc selon toi y a + de chances qu'une bibli qui fait un parsing générique propre et qui existe depuis PHP4 "oublie un cas" qu'un script écrit à l'arrache qui essaie tant bien que mal de gérer N cas spécifiques ?
 
Ben voyons. http://forum-images.hardware.fr/icones/message/icon14.gif


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 15:36:14    

sielfried a écrit :


 
Donc selon toi y a + de chances qu'une bibli qui fait un parsing générique propre et qui existe depuis PHP4 "oublie un cas" qu'un script écrit à l'arrache qui essaie tant bien que mal de gérer N cas spécifiques ?
 
Ben voyons. http://forum-images.hardware.fr/ic [...] icon14.gif


 
non, d'après moi utiliser une lib qu'on ne maitrise pas, dont on ne connait pas la qualité et qui n'est de toute manière pas faite pour résoudre le type de problème qu'on a n'est pas une bonne idée, point barre.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 15:52:28    

skeye a écrit :


 
non, d'après moi utiliser une lib qu'on ne maitrise pas, dont on ne connait pas la qualité et qui n'est de toute manière pas faite pour résoudre le type de problème qu'on a n'est pas une bonne idée, point barre.


 
Donc t'étudies le code source de toutes les biblis que t'utilises quand tu dév ? [:dawa]  
 
Parce que si tu parles de maîtrise de son API, y a vraiment rien de plus simplissime, franchement, je pense que ça se maîtrise "un peu" plus vite que les regexp, du coup.
 
Quant au "pas fait pour", no comment vu la solution que tu préconises, mais bon bref, on en a déjà causé et ça tourne en rond. :sleep:


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 15:57:13    

sielfried a écrit :

Donc t'étudies le code source de toutes les biblis que t'utilises quand tu dév ? [:dawa]  


 
Non. Mais je n'utilise pas des libs faites par des gens que je ne connais pas, dont je ne connais pas les compétences, et qui ne sont supportées par aucun organisme pseudo-officiel. Ce n'est pas parce-qu'un projet est hébergé sur sourceforge qu'il mérite une confiance aveugle, loin de là - les mainteneurs ce ces projets peuvent disparaitre du jour au lendemain sans que tu saches pourquoi et sans que personne ne les reprenne, t'auras juste l'air d'un con si ça ne marche pas comme prévu.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-12-2008 à 16:07:19    

Personne n'a dit que la bibli était fiable à 100% ou qu'il fallait faire confiance à sourceforge. Y a évidémment un risque, mais là en l'occurence il s'agit d'un projet actif, on sent que le mec assure un minimum, qu'il a pensé à son API, qu'il sait coder, qu'il sait ce qu'il fait. Du reste, je l'ai souvent vue recommandée dans des forums (anglophones pour la plupart) par des gens qui n'avaient pas non plus l'air d'être des truffes.
 
Je suis pas personellement fan de l'utilisation massive de libs de ce genre, mais y a parfois des perles et je vois pas pourquoi faudrait nécessairement se priver, quand le gain (ici en lisibilité/maintenabilité/rapidité de code) est significatif.


Message édité par sielfried le 04-12-2008 à 16:08:48

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 16:18:18    

Ça donnerait ça (non testé) :

Code :
  1. $player_tag = '<player ' . $input_string . ' />';
  2. $xml = new simple_html_dom();
  3. $xml->load($player_tag);
  4. $player = $xml->first_child();
  5. // Voilà, tout est dispo dans $player->ref_player, $player->num_position, etc


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 04-12-2008 à 18:56:59    

sielfried a écrit :

ou qu'un \" pouvait venir foutre le bazar.


Ca ne fout pas le bazar, vu que \" n'existe pas en XML. On utilise &quot; pour escaper

Reply

Marsh Posté le 04-12-2008 à 20:14:24    

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed