Expressions régulières et récursivité

Expressions régulières et récursivité - PHP - Programmation

Marsh Posté le 28-07-2004 à 16:25:48    

Salut tout le monde,
J'ai un problème sur lequel je bute depuis quelque temps, et personne ne semble savoir comment le résoudre. C'est du code PHP, mais ça vaut aussi pour Perl.
Je vais essayer de simplifier un max.
 
Au départ j'ai un texte :

Code :
  1. {un{deux}{deux{trois}}}{un}


Je veux le transformer pour qu'il devienne :

Code :
  1. [un[deux][deux[trois]]][un]


Vous vous doutez bien que dans le cas concret un simple str_replace ne suffit pas (en fait, il faut retraiter les données entre accolades, mais je simplifie ;)).
 
Je croyais avoir trouvé la solution avec la récursivité :

Code :
  1. echo preg_replace('/(\{ ( (?:   (?>[^{}]+)|(?1))*   )\})/xsi', '[\\2]', '{un{deux}{deux{trois}}}{un}');


Mais ça affiche :

Code :
  1. [un{deux}{deux{trois}}][un]


Tout va bien pour le premier niveau d'empilement. Mais comment faire pour que les accolades à l'intérieur d'autres accolades soient transformées aussi ? :??:
 
Merci !

Reply

Marsh Posté le 28-07-2004 à 16:25:48   

Reply

Marsh Posté le 28-07-2004 à 16:44:58    

A priori une grammaire est plus adaptée pour résoudre ton problème. Je crois pas qu'il y en ait de dispo en php, donc va falloir que tu te fasses ton parser.
 
//
 
hack rapide - tu peux transformer ton {un{deux{... en <tag>un<tag>deux</tag> etc avec un simple parsing de la chaîne - suffit de compter le nombre de { pour savoir quand ouvrir et fermer un tag. Ensuite, tu utilises domxml pour avoir ton arbre, faire tes modifs, puis le retransformer en chaîne. Tu utilises la manip inverse de parsing pour retransformer en les <tag> en ].

n°808869
youdontcar​e
Posté le 28-07-2004 à 16:47:00  profilanswer
 

Je dis des conneries, y'a même pas besoin de parser - deux str_replace suffiront.

n°808876
kalex
Posté le 28-07-2004 à 16:50:37  profilanswer
 

Ok, c'est ce que je me disais...
Merci à toi !
 
Je vais voir comment coder ça. :)

n°809255
kalex
Posté le 28-07-2004 à 23:02:26  profilanswer
 

J'ai bien compris l'astuce avec XML, mais comme j'aime bien faire les choses moi même (et me compliquer la vie ;)), j'ai fait ce truc :

Reply

Marsh Posté le 29-07-2004 à 01:11:57    

Code :
  1. $str = '{un{deux}{deux{{4}tro{4{5}}{}is}}}{un{deux}{deux{troi{4{5{6}}}s}}}';
  2. make_transfo(0, array(0));
  3. function make_transfo($start = 0, $back){
  4.         global $str;
  5.         $mstr = substr($str, $start);
  6. if(($ouv = strpos($mstr, '{')) !== FALSE AND ($fer = strpos($mstr, '}')) !== FALSE){
  7.  if($ouv > $fer AND isset($back[1])){
  8.   echo 'Retourne<br />';
  9.   $val = end($back);
  10.   $key = key($back);
  11.   unset($back[$key]);
  12.   make_transfo($val, $back);
  13.  }else{
  14.   $ouv2 = strpos(substr($mstr, $ouv+1), '{');
  15.   if($ouv2 !== FALSE AND ($ouv + $ouv2) < $fer){
  16.    echo 'Stoque<br />';
  17.    $back[] = $start+$ouv;
  18.    make_transfo($start+$ouv+$ouv2+1, $back);
  19.   }else{
  20.         echo 'Passe<br />';
  21.    $str = substr_replace($str, '['.substr($mstr, $ouv+1, $fer-$ouv-1).']', $ouv+$start, $fer-$ouv+1);
  22.    make_transfo($start+$fer+1, $back);
  23.   }
  24.  }
  25. }elseif(isset($back[1])){
  26.         echo 'fBack!<br />';
  27.         $val = end($back);
  28.  $key = key($back);
  29.  unset($back[$key]);
  30.  make_transfo($key, $back);
  31. }
  32. }
  33. echo $str;
kalex a écrit :

[...] mais comme j'aime bien faire les choses moi même (et me compliquer la vie ;)) [...] sa robustesse

Grave défaut. Le bon programmeur est flemmard et utilise l'existant plutôt que réinventer la roue. Ici tu as ton propre format & ton propre parser - tu aurais utilisé du xml, tu n'aurais pas à te poser ce genre de questions (format, robustesse & co).

Reply

Marsh Posté le 29-07-2004 à 03:50:43    

Je ne suis pas programmeur, mais je m'y connais assez pour savoir que c'est aussi une question de point de vue. Je suis d'accord avec toi, pour ce simple exemple, XML serait très pratique.
Mais je me méfie beaucoup de la réutilisation à tout va. A force on ne sait plus rien faire par soit même, on perd tout contrôle sur la monté en charge et la représentation des données (ex: les champs fulltext d'une bdd). Ensuite, je préfère passé 10 minute à modifier un code que je connais parfaitement plutôt qu'une heure à essayer de comprendre pourquoi ça bug avec du code qui n'est pas le mien. Sans parler de l'adaptation à une situation très particulière (comme ici).
PHP n'est pas le langage le plus adapté pour ça, c'est vrai.

Reply

Marsh Posté le 29-07-2004 à 05:44:00    

kalex a écrit :

mais je m'y connais assez pour savoir que c'est aussi une question de point de vue.

Si tu passes du temps à réinventer la roue et à la debugger, ce temps ne sera pas consacré à ton projet. Si tu considères perdre du temps comme un point de vue, tu devrais le revoir.
 

kalex a écrit :

Mais je me méfie beaucoup de la réutilisation à tout va. A force on ne sait plus rien faire par soit même,

Tu peux remonter encore plus loin. Si tu as envie de tout maitriser, pourquoi ne créé-tu pas ton langage ? Ton serveur web ? Ton processeur ? Les libs sont là pour abstraire un mécanisme connu et permettre des applications nouvelles. Mieux vaut apprendre à les utiliser correctement plutôt que de faire sa tambouille qui sera forcément moins efficace et plus buggée.
 

kalex a écrit :

Ensuite, je préfère passé 10 minute à modifier un code que je connais parfaitement plutôt qu'une heure à essayer de comprendre pourquoi ça bug avec du code qui n'est pas le mien.

Le temps que tu passeras à apprendre un standard te permettra d'utiliser ce standard partout, autant dans la relecture de ton code que celui des autres. Reviens dans 6 mois debugger ta méthode custom, tu auras bien du mal.

Reply

Marsh Posté le 29-07-2004 à 15:29:02    

Attends... j’ai jamais dis qu'il ne fallait pas réutiliser de code.
Par contre, réutiliser du code systématiquement parce que "c'est déjà fait"... Comment veux-tu apprendre avec cette méthode ? Comment veux-tu innover ? adapter ?
Les standards ? Aucun standard ne dit que pour transformer des accolades il faut passer par XML. Ca me parait un peu lourd et ça ajoute des contraintes (celles d'XML justement) dans le format du texte source. Adieux tolérance aux erreurs et comportement spécifique !
Autant tout faire en XML, et ça c'est pas possible ici.
 
Enfin, tout serait si simple si une petite regex marchait...


Message édité par kalex le 30-07-2004 à 03:19:47
Reply

Marsh Posté le 29-07-2004 à 15:35:38    

Tiens, récemment j'ai vu que JF Maquiné d'onversity a trouvé une méthode d'optimisation des boucles pour des fonctions de bases. Lorsqu'il a commencé à travailler là dessus, lui aurais-tu dit qu'il réinventait la roue ?

Reply

Marsh Posté le 29-07-2004 à 15:35:38   

Reply

Marsh Posté le 29-07-2004 à 20:19:01    

Si tu utilises des mécanismes standard, c'est autant de temps gagné à ne pas définir de formats, écrire de parser, etc. Tu dis que tu n'es pas programmeur, tu pourrais utiliser ces mécanismes pour gagner du temps et innover une application dans ton domaine d'expertise. Au lieu de ça, tu réinventes très mal la hiérarchie - tu as ton format, ta méthode de parsing, et tes bugs.

Reply

Marsh Posté le 30-07-2004 à 03:18:43    

Souvent tu n'as pas de prise sur le format à traiter... Sinon tu penses bien que j'utiliserais directo XML.

Reply

Marsh Posté le 30-07-2004 à 04:14:20    

$phrase = "{ comme {on { dit { chez nous}}ben}ca le fait}";
$phrase = ereg_replace('{', '[', $phrase);
$phrase = ereg_replace('}', ']', $phrase);
echo $phrase;//contient la phrase [ comme [on [ dit [ chez nous]]ben]ca le fait}]


---------------
!jb!
Reply

Marsh Posté le 30-07-2004 à 04:14:50    

je reve pas, c beaucoup plus simple???


---------------
!jb!
Reply

Marsh Posté le 30-07-2004 à 13:04:39    

Oui, mais j'ai dit dans le premier post qu'il fallait en fait retraiter les données entre accolades, mais que je simplifiais  volontairement. Merci quand même !

Reply

Marsh Posté le 30-07-2004 à 13:13:30    

Est ce que ce cas est possible ?  
{blabla{blibli}blabla2} {bloblo}
 
En gros, est-ce les blocs s'imbriquent uniquement ou il risque d'y avoir des blocs cote a cote ?

Reply

Marsh Posté le 30-07-2004 à 13:43:41    

Oui, les blocs peuvent se suive.

Reply

Sujets relatifs:

Leave a Replay

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

© 2018 Forum. All Rights Reserved.