Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1608 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Expressions régulières et récursivité

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Expressions régulières et récursivité

n°808834
kalex
Posté le 28-07-2004 à 16:25:48  profilanswer
 

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 !

mood
Publicité
Posté le 28-07-2004 à 16:25:48  profilanswer
 

n°808867
youdontcar​e
Posté le 28-07-2004 à 16:44:58  profilanswer
 

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 :

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;


Il reste à l'adapter et à vérifier sa robustesse, ça promet. :D Ou à tout mettre à la poubelle si vous me dites qu'il y a mille fois plus simple...


Message édité par kalex le 28-07-2004 à 23:03:33
n°809432
youdontcar​e
Posté le 29-07-2004 à 01:11:57  profilanswer
 

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).

n°809451
kalex
Posté le 29-07-2004 à 03:50:43  profilanswer
 

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.

n°809460
youdontcar​e
Posté le 29-07-2004 à 05:44:00  profilanswer
 

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.

n°810066
kalex
Posté le 29-07-2004 à 15:29:02  profilanswer
 

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
n°810075
kalex
Posté le 29-07-2004 à 15:35:38  profilanswer
 

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 ?

mood
Publicité
Posté le 29-07-2004 à 15:35:38  profilanswer
 

n°810433
youdontcar​e
Posté le 29-07-2004 à 20:19:01  profilanswer
 

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.

n°810635
kalex
Posté le 30-07-2004 à 03:18:43  profilanswer
 

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

n°810642
lunarnet76
Posté le 30-07-2004 à 04:14:20  profilanswer
 

$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!
n°810643
lunarnet76
Posté le 30-07-2004 à 04:14:50  profilanswer
 

je reve pas, c beaucoup plus simple???


---------------
!jb!
n°811074
kalex
Posté le 30-07-2004 à 13:04:39  profilanswer
 

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 !

n°811083
karamilo
Posté le 30-07-2004 à 13:13:30  profilanswer
 

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 ?

n°811118
kalex
Posté le 30-07-2004 à 13:43:41  profilanswer
 

Oui, les blocs peuvent se suive.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Expressions régulières et récursivité

 

Sujets relatifs
Expressions regulières et sous motifsLes expressions régulières
[PHP] Expressions régulières... [Résolu]Expressions rationnelles et caractère "?"
[PHP] accents inclus ou non dans les expressions rationelles [a-z]probleme de recursivite
petit probleme de recursivité 
Plus de sujets relatifs à : Expressions régulières et récursivité


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR