Besoin d'aide pour un remplacement de chaine par expression régulière.

Besoin d'aide pour un remplacement de chaine par expression régulière. - PHP - Programmation

Marsh Posté le 17-01-2007 à 10:50:16    

Bonjour,
 
Je sollicite votre aide, étant donné mon faible niveau en regexp. je dois faire un remplacement de chaine comme suit:
 

Code :
  1. $texte = 'blablablabla ...';
  2. $texte = preg_replace($tableau_motifs, $tableau_replace, $texte);


 
Le souci, c'est que dans le texte, je dois remplacer les motifs SAUF ceux se trouvant entre deux tags utilisant la mise en forme [tag]......[/tag].
 
j'ai fait quelques tests pour le motif, mais le problème, c'est que travaillant avec des tableaux, je ne vois pas comment spécifier qu'il ne faut rien remplacer entre les deux tags.
D'avance, merci de votre aide!

Reply

Marsh Posté le 17-01-2007 à 10:50:16   

Reply

Marsh Posté le 17-01-2007 à 14:08:09    

c'est quoi un motif pour toi ?
un exemple autre que "blablabla" serait plus parlant
 
tu connais les assertions sinon ?

Reply

Marsh Posté le 17-01-2007 à 14:14:09    

Le motif? Pour moi c'est la masque de recherche que la fonction doit remplacer. pour le texte, j'ai mis un truc générique... Si je devais mettre quelque chose qui soit exactement ce que je cherche à faire ce serait dans ce genre là :
 

Code :
  1. $texte = "ceci est une phrase contenant n'importe quoi avec [ignore]des choses à ne pas traiter entre des tags[/ignore]. la chaine peut contenir de tout"

Reply

Marsh Posté le 18-01-2007 à 11:08:44    

Avec des assertions ça va être compliqué...
 
Je vois 2 méthodes :
- tu fais une regexp qui cherche les morceaux qui ne sont pas entre tags, et tu fais ton replace sur ces morceaux (voir option e de recherche) => si n morceaux on aura donc n+1 preg_replace
- tu extraits les morceaux entre tags (tu les remplaces par un genre de flag), tu fais ton replace, tu replaces les morceaux => 3 preg_replace
 
Je pense que la 2ème méthode est moins gourmande, mais ça dépend aussi de la complexité de tes masques.

Reply

Marsh Posté le 18-01-2007 à 12:48:23    

J'avais fait quelque chose comme ça (qui correspond à peu près à la seconde suggestion de soju). Y a peut-être (sûrement ?) plus efficace (style une regexp miracle), mais en attendant ça fonctionne.
 

Code :
  1. function preg_replace_except_inside_bbcode($pattern, $replacement, $subject, $temp_flag = '###~FOLDED~###') {
  2.  // Capturing BBCode into an array
  3.  $bbcode_capture_pattern = '#\[([^]]*)\].*\[/\\1\]#isU';
  4.  if (preg_match_all($bbcode_capture_pattern, $subject, $matches) == false) {
  5.    return false;
  6.  }
  7.  if (count($matches) == 0) {
  8.    return $subject;
  9.  }
  10.  $folded_entities = $matches[0];
  11.  
  12.  // Folding BBCode inside initial text
  13.  $folded_subject = preg_replace($bbcode_capture_pattern, $temp_flag, $subject);
  14.  
  15.  // Splitting subject into "outside of BBCode parts"
  16.  $subject_parts = split($temp_flag, $folded_subject);
  17.  
  18.  // Applying requested replace + unfolding
  19.  $subject = preg_replace($pattern, $replacement, $subject_parts[0]);
  20.  for ($i = 1; $i < count($subject_parts); $i++) {
  21.    $subject .= $folded_entities[$i - 1] . preg_replace($pattern, $replacement, $subject_parts[$i]);
  22.  }
  23.  
  24.  return $subject;
  25. }


 
À noter que ça ne prend pas en compte les params facultatifs de preg_replace, parce que j'en n'avais pas eu besoin. Mais ça doit pouvoir se faire.


Message édité par sielfried le 18-01-2007 à 12:50:41

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

Marsh Posté le 18-01-2007 à 13:52:31    

ta solution de splitter le texte n'est pas bête du tout... j'avais réfléchi hier soir à une solution qui ressemblait à l'extraction de la partie à ne pas traiter suggérée par soju. je vais essayer les deux méthodes et voir laquelle est la plus performante! En tout cas, merci beaucoup à tous les deux pour vos conseils! :)

Reply

Marsh Posté le 18-01-2007 à 21:11:05    

Code :
  1. <?php
  2. $texte = 'pouet pouet [ignore]pouet pouet[/ignore] pouet pouet [ignore]pouet pouet[/ignore] pouet pouet';
  3. $pattern = '#(?:^|\\[/ignore\\])(.*)(?:\\[ignore\\]|$)#Ue';
  4. $replace = 'str_replace("pouet" , "prout" , "$1" )';
  5. $res = preg_replace($pattern , $replace , $texte);
  6. echo $res;
  7. ?>

Qui donne comme résultat :

Code :
  1. pouet pouet [ignore]pouet pouet[/ignore] pouet pouet [ignore]pouet pouet[/ignore] pouet pouet
  2. -->
  3. prout prout pouet pouet prout prout pouet pouet prout prout

Il faut noter que ca vire les [ignore] mais il est pas bien dur de les conserver :)

Reply

Marsh Posté le 18-01-2007 à 21:24:56    

Ah ben ouais. [:pingouino]  
 
C'est tellement con que je n'y avais pas pensé. [:dawa]


Message édité par sielfried le 18-01-2007 à 21:25:25

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

Sujets relatifs:

Leave a Replay

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