un gourou de le regexp dans la salle?

un gourou de le regexp dans la salle? - PHP - Programmation

Marsh Posté le 31-08-2007 à 09:12:39    

Salut ;)
 
Voila, j'ai un petit probleme, dans un outils de conversion de fiche produit html vers PDF, je dois modifier toutes les balises <span style="color:#xxxxxx">blablabla</font> vers <c:style:#xxxxxx>. CA j'arrive à le faire via ce code PHP :

Code :
  1. $finalOutput =  preg_replace_callback(
  2.             '/<span( +)style="color:( *)(#[0-9a-fA-F]+);"( *)>([^<]*)<\\/span>/',
  3.             create_function(
  4.              '$matches',
  5.              '$size =  ":null";
  6.     $color = (!empty($matches[3])) ? "&".$matches[3] : "&null";
  7.     $output = "<c:style".$size.$color.">".$matches[5]."</c:style>";
  8.     return $output;'
  9.      ),
  10.           $output);
  11.   return $output;


 
Le probleme c'est qu'il peux y avoir des balises span imbriquées et CA, ma regexp ne le gere pas.. comment faire? car en gros j'ai mon pattern :

Code :
  1. '/<span( +)style="color:( *)(#[0-9a-fA-F]+);"( *)>([^<]*)<\\/span>/'


mais entre les deux balises span, il faudrait que je puisse dire qu'il puisse y avoir encore une fois mon pattern à l'interieur de ces balises, puis a l'interieur de ce meme pattern encore un fois mon pattern.. bref ca ressemble à du recursif.. en gros ma regexp doit pouvoir gérer ce cas tordu par les cheveux :
<span style="color:#xxxxxx"><span style="color:#xxxxxx">blab<span style="color:#xxxxxx">blabla<span style="color:#xxxxxx">blablabla</font>bla</font>labla</font></font>
 
comment faire ?

Reply

Marsh Posté le 31-08-2007 à 09:12:39   

Reply

Marsh Posté le 31-08-2007 à 11:25:55    

Dégloutonne ton masque avec /.../U (e.g '/<span( +)style="color:( *)(#[0-9a-f]+);"( *)>(.*)<\\/span>/Ui')


Message édité par Bouchon2 le 31-08-2007 à 11:43:09
Reply

Marsh Posté le 01-09-2007 à 15:26:39    

Si tu veux un truc récursif le U ne va a priori pas suffire (et va même provoquer des incohérences). Faut utiliser (?R) qui est fait pour, mais c'est vite la prise de tête. [:dawa]
 
J'avais déjà fait un truc similaire donc je viens de jouer un peu avec pour l'adapter à ce que tu cherches :

Code :
  1. $pattern = '/<span.*?style=["\']?color:#([0-9a-fA-F]+);?["\']?[^>]*>((?:(?!<\/?span).)*(?R).*?|.*?)<\/span>/s';
  2. function replace($matches) {
  3.  global $pattern;
  4.  list(, $color, $value) = $matches;
  5.  return '<c:style:#' . $color . '>'
  6.       . preg_replace_callback($pattern, 'replace', $value)
  7.       . '</c>';
  8. }
  9. $foo = '<span style="color:#cccccc">aaa</span><span style="color:#cccccc">bbb<span style="color:#cccccc">ccc<span style="color:#cccccc">ddd</span></span>eee</span>';
  10. $foo = preg_replace_callback($pattern, 'replace', $foo);


Message édité par sielfried le 01-09-2007 à 15:35:04

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

Marsh Posté le 01-09-2007 à 17:25:20    

Autre solution plus simple que ?R (qui reste une bonne idée d'ailleurs)
 

Code :
  1. do{
  2. $output = preg_replace('@<span +style=["\']?color: *(#[0-9a-f]+);["\']? *>(.*)</span>@i', '<c:style:\\1>\\2</c:style>', $t, -1, $c);
  3. }while($c);


Reply

Marsh Posté le 01-09-2007 à 20:38:58    

OK merci beaucoup les mecs ;) Effectivement il fallait connaitre ces parametres sêciaux (et savoir les utiliser surtout)
 
je vois ca lundi ;)

Reply

Marsh Posté le 01-09-2007 à 22:37:46    

Bouchon2 a écrit :

Autre solution plus simple que ?R (qui reste une bonne idée d'ailleurs)
 

Code :
  1. do{
  2. $output = preg_replace('@<span +style=["\']?color: *(#[0-9a-f]+);["\']? *>(.*)</span>@i', '<c:style:\\1>\\2</c:style>', $t, -1, $c);
  3. }while($c);




 
En effet, par contre faut rajouter le mode U là.
 
J'avais pensé à ça à l'époque je crois, mais on devait être à PHP < 5.1 et donc y avait pas ce fameux paramètre $count. :)


Message édité par sielfried le 01-09-2007 à 22:38:58

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

Marsh Posté le 10-09-2007 à 13:15:29    

J'ai aussi un problème de reg exp (enfin je crois...)
 
Je voudrais écrire un interprète syntaxique qui parcourt un bout de code et qui puisse mettre en gras les mots clés du langage. Pour ça, je dois remplacer dans le bout de code toutes les occurences des mots-clés du language que j'ai écrit dans un tableau, mais seulement si ils sont entourés de caractères non alphanumériques.
Donc j'utilise une expression régulière pour ça, mais après, quand je remplace le mot par le mot balisé, il faut pas que je remplace aussi les caractères qui étaient autour, sous peine de rendre le code erroné. je m'explique :  
 
preg_replace( '/[^a-zA-Z0-9_]'.$mots[$i].'[^a-zA-Z0-9_]/', '<b>'.$mots[$i].'<b>', $code);
 
a l'inconvénient de remplacer " string " par "<b>string<b>". C'est pourquoi je demande si quelqu'un sait
1) si ma démarche est la bonne
2) comment utiliser les parenthèses dans cette fonction pour ne remplacer qu'une partie de l'expression régulière


Message édité par liquidcloud le 10-09-2007 à 13:17:16
Reply

Marsh Posté le 10-09-2007 à 14:29:14    

Je recommande l'utilisation de \b dans ton cas, c'est un caractère non capturé et qui veut dire "début de mot" ou "fin de mot".
 
/\bstring\b/ captera ainsi le mot "string", qu'il y ait de la ponctuation autour ou pas et quelle qu'elle soit.
 
Bref essaie un truc genre :
preg_replace('/\b(mot1|mot2|mot3)\b/', '<b>\\1</b>', $code)

Message cité 1 fois
Message édité par sielfried le 10-09-2007 à 14:29:33

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

Marsh Posté le 10-09-2007 à 15:58:12    

sielfried a écrit :

Je recommande l'utilisation de \b dans ton cas, c'est un caractère non capturé et qui veut dire "début de mot" ou "fin de mot".
 
/\bstring\b/ captera ainsi le mot "string", qu'il y ait de la ponctuation autour ou pas et quelle qu'elle soit.
 
Bref essaie un truc genre :
preg_replace('/\b(mot1|mot2|mot3)\b/', '<b>\\1</b>', $code)


 
Merci beaucoup de ta précision sur le \b, ça m'a été bien utile ... Néanmoins, ça n'a pas réglé mon problème, mais je viens de m'apercevoir au terme de 4 jours de puissante fatigue intellectuelle que pg_replace était une fonction et pas une procédure ... C'est pour ça que mon code ne se mettait pas en gras! :heink:  

Reply

Sujets relatifs:

Leave a Replay

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