[résolu] Regex pour identifier les bons couples span /span

Regex pour identifier les bons couples span /span [résolu] - PHP - Programmation

Marsh Posté le 25-05-2009 à 11:18:37    

Bonjour,  
 
Je dois gérer un système où un logiciel génère ce genre de code :
fkgfgf <immediat><majeur><couteux>rzerzere</couteux>zerzerrze<peucouteux>fdsfdsfsd></peucouteux></majeur>fsdfsdfsdf</immediat>
Donc un système de tags imbriqués (un peu dans n'importe quel ordre, celui de leur saisie). Jusque là, aucun soucis particulier.
 
 
Le problème que je rencontre se situe au niveau de la relecture de fichiers édition qui sont les mêmes que les précédents, excepté le fait que les couples <tag>xxxx</tag> sont remplacés par des <span class='tag'>xxxx</span>
 
ce qui donne dans mon exemple précédent :
fkgfgf <span class='immediat'><span class='majeur'><span class='couteux'>rzerzere</span>zerzerrze<span class='peucouteux'>fdsfdsfsd></span></span>fsdfsdfsdf</span>
 
Or il faut que je convertisse ce fichier édition dans le format précédent
 
 
Une boucle de :

Code :
  1. $item = preg_replace('#<span class=\'(immediat|rapide|lent|immobile|critique|majeur|mineur|optionnel|investplanifie|couteux|peucouteux|gratuit)\'>(.*?)</span>#', "<$1>$2</$1>", $item);


fonctionne partiellement mais a le grand désavantage de mettre les balises fermantes la plupart du temps au mauvais endroit.
 
 
 
Ce que je n'arrive pas à exprimer c'est une chaine ne contenant pas une sous-chaine.
J'ai besoin de dire dans un preg_replace : une chaine qui commence par <span class qui se termine par </span> et qui ne contient pas <span et c'est cette dernière partie que je ne parviens pas à encoder car je ne sais pas comment l'écrire.
 
A noter que :

Code :
  1. $idem = preg_replace('#<span class=\'(immediat|rapide|lent|immobile|critique|majeur|mineur|optionnel|investplanifie|couteux|peucouteux|gratuit)\'>([^<]*?)</span>#', "<$1>$2</$1>", $item);


pour dire
une chaine qui commence par <span class qui se termine par </span> et qui ne contient pas < fonctionne très bien. Mais ce n'est pas ce que je souhaite
 
 
J'ai essayé plein de choses, par exemple :
 

Code :
  1. $idem = preg_replace('#<span class=\'(immediat|rapide|lent|immobile|critique|majeur|mineur|optionnel|investplanifie|couteux|peucouteux|gratuit)\'>((^(<span))*?)</span>#', "<$1>$2</$1>", $item);


 
pour essayer de ne remplacer un couple <span </span> que s'il n'y a pas de <span entre les deux
 
Mais mes syntaxes ne fonctionnent pas.
 
 
 
 
J'ai essayé de rechercher un topic qui parle un peu de ce sujet dans le forum mais sans vraiment trouver une solution à mon besoin.
 
 
Merci d'avance pour vos avis éclairés.


Message édité par dandes91 le 26-05-2009 à 11:58:16
Reply

Marsh Posté le 25-05-2009 à 11:18:37   

Reply

Marsh Posté le 25-05-2009 à 12:49:51    

avec un outil type DOM ?

Reply

Marsh Posté le 25-05-2009 à 13:03:12    

tomsoft a écrit :

avec un outil type DOM ?


 
Je ne sais pas utiliser DOM et n'y comprends pas grand chose. Ca a l'air à priori hyper compliqué, surtout pour ce que je veux faire.
Ceci dit, je n'ai rien contre, si quelqu'un veut bien me donner la solution DOM pour passer facilement de :
 

Code :
  1. fkgfgf <span class='immediat'><span class='majeur'><span class='couteux'>rzerzere</span>zerzerrze<span class='peucouteux'>fdsfdsfsd></span></span>fsdfsdfsdf</span>


 
à
 

Code :
  1. fkgfgf <immediat><majeur><couteux>rzerzere</couteux>zerzerrze<peucouteux>fdsfdsfsd></peucouteux></majeur>fsdfsdfsdf</immediat>


 
je suis preneur mais tout seul ça m'étonnerait que j'y parvienne.
 
 
 
Sinon si je reformule mon problème Regex :
 
Ce que je n'arrive pas à exprimer c'est une chaine ne contenant pas une sous-chaine.
 
([^<]*?) exprime bien n'importe quelle chaine qui ne contient pas <
si j'avais l'équivalent pour  n'importe quelle chaine qui ne contient pas <span je serais sauvé
 
((^(<span))*?) n'a pas l'air de fonctionner, de même tout ce que j'ai essayé.
On doit bien pouvoir exprimer : une chaine qui ne contient pas telle sous-chaine.  
Je me dis qu'à priori cela ne doit être qu'un problème de syntaxe


Message édité par dandes91 le 25-05-2009 à 16:54:26
Reply

Marsh Posté le 25-05-2009 à 20:44:29    

La négation ^ n'existe que pour les classes de caractères, pas pour les chaînes.  
 
Regarde du coté des masques récursif (?R), ça t'évitera une boucle et peut-être que de la sorte, ça marcherait. (j'en doute... :()

Reply

Marsh Posté le 26-05-2009 à 11:46:46    

guybrush02 a écrit :

La négation ^ n'existe que pour les classes de caractères, pas pour les chaînes.


 
 
D'accord, si tu le dis, je te fais confiance.
 
 
Mais cela m'a donné l'intuition d'une bidouille pour parvenir à mes fins.
 
Je commence par transformer les <span class=' par un caractère unique µ (que je prends soin de transformer en une chaine bidon)
 

Code :
  1. $a1 = array("µ", "<span class='" );
  2. $a2 = array("§çk£e£", "µ" );
  3. $item = str_replace($a1, $a2, $item);


 
puis je fais ma boucle de :
 

Code :
  1. $idem = preg_replace('#µ(immediat|rapide|lent|immobile|critique|majeur|mineur|optionnel|investplanifie|couteux|peucouteux|gratuit)\'>([^µ]*?)</span>#', "<$1>$2</$1>", $item);


 
et je restaure mon caractère unique précédemment sauvegardé :
 

Code :
  1. $tag11 = array("§çk£e£" );
  2. $tag21 = array("µ" );
  3. $texte = str_replace($tag11, $tag21, $texte);


 
 
 
Et cela correspond pile poil à mon besoin. Je peux même traiter les div sur le même modèle.
Cette méthode peut même être généralisée pour n'importe quelle exclusion de pattern fixe et connu à priori, il suffit de réduire ce pattern en  caractère spécial
 
Certes, c'est pas du code hightech, mais le principal c'est que cela fonctionne (c'est ce que demande mon employeur).
 
Encore merci pour l'intuition


Message édité par dandes91 le 26-05-2009 à 11:55:50
Reply

Sujets relatifs:

Leave a Replay

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