Remplacer une chaine multiple dans un fichier

Remplacer une chaine multiple dans un fichier - PHP - Programmation

Marsh Posté le 20-11-2009 à 16:56:30    

Bonjour,
Voilà je voulais savoir si qq'un avait une idée qui pourrait m'aider à résoudre mon problème.
 
Je dispose d'un fichier .txt qui ressemble à du XML avec des balises en gros ...
{AB:XXXXXXXX}{CD:YYYYYYYY}{blbablblablbalbalbalbal}{AB:XXXXX} et ainsi de suite ...  
 
Je voudrais créér un script php qui permetrait que pour chaque chaines commencant par {AB: remplacer les 8 caractères qui suivent (donc dans l'exmple les XXXXXXXX) par 8 autres caractères, même chose avec {CD: ...
 
Le bout de code ci-dessous fonctionne mais ne traite qu'une seule fois la demande ... en clair il trouve l'occurence, il positionne le curseur et remplace les 8 caractères qui suivent ... par uuuuuuuu. Seulement voila dans le fichier il y a plusieurs BLOC 1 et BLOC 2 ... donc logiquement il devrait bouclé ? mais non :)
 
Si qq'un à une idée ... avec un foreach $contenu as $contenu ? ca pourrait le faire ?
 

Reply

Marsh Posté le 20-11-2009 à 16:56:30   

Reply

Marsh Posté le 20-11-2009 à 17:14:55    

on dirait du json, s'en est a la base ?


Message édité par stealth35 le 20-11-2009 à 17:25:34
Reply

Marsh Posté le 20-11-2009 à 17:38:44    

vu que tu n'as aucune instruction de boucle genre for ou while, ça ne peut pas boucler.

 

Tu devrais faire une fonction (comme tu as deux "blocs" à trouver, tu pourras l'appeler deux fois de suite), en pseudo-code ça donnerait (j'avoue avoir la flemme de faire une syntaxe correcte :D) :

 

function mafonction ($bloc, $stream) {

 

 je recherche bloc dans stream à partir de la position de départ
  tant qu'on trouve bloc dans stream {
    je remplace la chaîne qui va bien dans stream en utilisant la position trouvée
    je fais progresser la position de départ en tenant compte du nombre de caractères ainsi remplacés
    je recherche bloc dans stream à partir de la nouvelle position de départ
  }
  return stream
}

 

La dernière ligne du while servant à démarrer ta recherche à partir de la dernière occurence trouvée.


Message édité par Fred999 le 20-11-2009 à 17:39:28
Reply

Marsh Posté le 20-11-2009 à 18:25:22    

un coup de regexp et le tour est joué de toute facon

Reply

Marsh Posté le 23-11-2009 à 10:29:41    

Merci pour votre aide ;)
On se moque pas je débute ... mais voilà une ébauche de ce que j'aimerais donc faire ... sauf que ca me met des erreurs :(
 

Code :
  1. $fichier = "test.txt";
  2. //ouverture en lecture et modification  
  3. $text=fopen($fichier,'r') or die("Fichier manquant" );
  4. $contenu=file_get_contents($fichier);
  5. // BLOC 1
  6. $findme_bloc1   = '{AB:';
  7. $pos_bloc1 = strpos($contenu, $findme_bloc1);
  8. if ($pos_bloc1 !== false)
  9. {
  10. $pos_bloc1 = $pos_bloc1 + 4;
  11. $contenuMod = substr_replace($contenu, 'uuuuuuuu', $pos_bloc1, 8);
  12. }
  13. // BLOC 2
  14. $findme_bloc2   = '{CD:';
  15. $pos_bloc2 = strpos($contenuMod, $findme_bloc2);
  16. if ($pos_bloc2 !== false)
  17. {
  18. $pos_bloc2 = $pos_bloc2 + 4;
  19. $contenuMod2 = substr_replace($contenuMod, 'uuuuuuuu', $pos_bloc2, 8);
  20. }
  21. fclose($text);
  22. //ouverture en écriture  
  23. $text2=fopen($fichier,'w+') or die("Fichier manquant" );
  24. fwrite($text2,$contenuMod);
  25. fclose($text2);
Code :
  1. <?php
  2. $fichier = "test.txt";
  3. function CheckBloc ($bloc, $stream,$replace,$pos)
  4. {
  5. $pos_bloc = 0;
  6. while ($pos_bloc = strpos($stream,$bloc,$pos_bloc))
  7. {
  8.  $pos_bloc = $pos_bloc + $pos;
  9.  $stream = substr($stream,$replace,$pos_bloc,8);
  10. }
  11. return $stream;
  12. }
  13. //ouverture en lecture et modification  
  14. $text=fopen($fichier,'r') or die("Fichier manquant" );
  15. //$contenu=file_get_contents($fichier);
  16. $contenu = file($fichier);
  17. $contenu_new = CheckBloc('{AB',$contenu,'uuuuuuuu',6);
  18. $contenu_new = CheckBloc('{CD:',$contenu_new,'uuuuuuuu',4);
  19. fclose($text);
  20. //ouverture en écriture  
  21. $text2=fopen($fichier,'w+') or die("Fichier manquant" );
  22. fwrite($text2,$contenu_new);
  23. fclose($text2);
  24. ?>


Warning: strpos() expects parameter 1 to be string, array given in D:\PRIV\EasyPHP5.3.0\www\test.php on line 7
Warning: strpos() expects parameter 1 to be string, array given in D:\PRIV\EasyPHP5.3.0\www\test.php on line 7
Warning: fwrite() expects parameter 2 to be string, array given in D:\PRIV\EasyPHP5.3.0\www\test.php on line 25
 
Je capitule :p
 
Merci pour votre aide si vous avez une idée ...  
Cordialement


Message édité par Odissine le 23-11-2009 à 11:29:32
n°1943361
Fred999
Rabat-joie
Posté le 23-11-2009 à 10:31:13  profilanswer
 

fais un print_r($stream) ça devrait aider...

n°1943406
Odissine
Posté le 23-11-2009 à 11:30:20  profilanswer
 

Ok merci Fred, mais heu ... je pense que le problème est ailleurs :p ... l'erreur se situe dans la boucle ... mais je pige pas :s

n°1943431
stealth35
Posté le 23-11-2009 à 11:52:44  profilanswer
 

apres tout depen de se que t'as vraiement dans 'xxxxx' et 'yyyyy'  (la j'ai mis que des lettres)

Code :
  1. $str = "{AB:XXXXXXXX}{CD:YYYYYYYY}{blbablblablbalbalbalbal}{AB:XXXXX}";
  2. //$str = file_get_contents('file.txt');
  3.     
  4. $pat = '/(\{(AB|CD):)(\w+)(\})/';
  5. $rep = '\1uuuuuuuu\4';
  6.     
  7. $new = preg_replace($pat, $rep, $str);
  8. //file_put_contents('file.txt', $new);
  9.  
  10. echo $new
  11.  
  12. // {AB:uuuuuuuu}{CD:uuuuuuuu}{blbablblablbalbalbalbal}{AB:uuuuuuuu}
Reply

Marsh Posté le 23-11-2009 à 15:07:21    

Ton mini script sur le json me renvoi le contenu exacte de mon fichier ...
Ceci dit voilà en gros ce que contient un fichier réellement :
 
{1:F01AAAAAAAAAXXX2269001727}{2:I101YYYYYYYYXXXXN}{4:TEXTE}${1:F01AAAAAAAAAXXX2269001727}{2:I999YYYYYYYYXXXXN}{4:TEXTE}${1:F01AAAAAAAAAXXX2269001727}{2:O199YYYYYYYYXXXXN}{4:TEXTE}
[...] et ainsi de suite ...
En clair un fichier contenu plusieurs "message" formaté avec un bloc 1, un bloc 2 et un bloc 4 ... mon but est donc de remplacer dans le bloc 1 et 2 les AAAAAAAA et YYYYYYYY par uuuuuuuu (sachant que les AA et YY peuvent avoir des valeurs différentes à chaque fois ...  
- Pour le BLOC 1 les 6 premiers caractères sont toujours les mêmes (donc simple je remplace les 8 caractères suivants ... par uuuuuuuu et je laisse le reste ...
- Pour le BLOC 2 j'ai }{2: qui ne change pas, les trois autres caractères peuvent varier de 001 à 999 je remplace les 8 caratères suivants et je touche pas au reste ...
Pour être plus clair, les parties en rouges dans les blocs sont à remplacer par "uuuuuuuu" et seulement ce qui est en rouge ...
 
Merci Stealth je progresse ... par contre pourrais tu m'expliquer ce que veux dire 1 et 4 dans ta variable - $rep = '\1uuuuuuuu\4'; -
 
je vais y arriver ;) merci à vous en tout cas ...

n°1943550
stealth35
Posté le 23-11-2009 à 15:29:40  profilanswer
 

je change l'expression pour que ca marche avec ton truc,
 
pour les \1 et \4 enfaite c'est les groupes
 
groupe 1 = {AB:
groupe 2 = AB
groupe 3 = XXXXXXX
groupe 4 = }

Reply

Marsh Posté le 23-11-2009 à 15:29:40   

Reply

Marsh Posté le 23-11-2009 à 15:40:37    

Merci encore pour ton aide ... seulement voilà ... le script que tu m'as donné et replacé dans mon contexte donnerai à peut pret ca :  
 

Code :
  1. $text = fopen($fichier,'r') or die("Fichier manquant" );
  2. $str = file_get_contents('test.txt');
  3. $pat = '/(\{1:F01)(\w+)(\})/';
  4. $rep = '\1uuuuuuuu\4';
  5. $new = preg_replace($pat, $rep, $str);
  6. fclose($text);
  7. $text = fopen($fichier,'w+') or die("Fichier manquant" );
  8. fwrite($text,$new);
  9. fclose($text);


Malheureusement voilà le résultat :( ...
 
Avant : {1:F01AAAAAAAAXXX2269001727}{2:I101YYYYYYYYXXXXN}{4:
Après : {1:F01uuuuuuuu{2:I101YYYYYYYYXXXXN}{4: ...
 
Il m'a remplacé tout ce qu'il y avait apres les AAAAAAAA chiffres et accolades compris ... du coup quand je veux repasser ce script pour le bloc 2 ca fonctionne pas car je prend comme caractères : - }{2: -
 
Je vais y arriver ;)

n°1943561
stealth35
Posté le 23-11-2009 à 15:44:06  profilanswer
 

voila

 
Code :
  1. $pat = '/(\{\d+:\w\d+)(\w{8})(\w+\})/';
  2. $rep = '\1uuuuuuuu\3';
Reply

Marsh Posté le 23-11-2009 à 15:56:42    

Je pensais pas que ca allait etre si complexe :p ... Je pensais simplifier les choses en mettant A et Y ...
 
En vérité le contenu ressemble plutot à ca :  
 
{1:F01ABCDEFGHXXX2269001727}{2:I101IJKLMNOPXXXXN}{4:TEXTE}${1:F01ABCDEFGHXXX2269001727}{2:I999QQRSTUVWXXXXN}{4:TEXTE}${1:F01ABCDEFGHXXX2269001727}{2:O199KBFGRHUKXXXXN}{4:TEXTE} ...
Donc malheureusement ton script de prend les 8 caractères A ou Y ... marche po :( ...
 
Je suis sincèrement désolé :) en tout cas merci encore pour ton aidre !
 
Tu comprends mieux peut etre maintenant pourquoi je veux le remplacer par uuuuuuuu ... je veux uniformiser les informantions :) si c'était déjà A et Y ... je demanerais pas ca ;)
 
Merci par avance !

Reply

Marsh Posté le 23-11-2009 à 15:57:05    

c'est bon j'ai modifié

Reply

Marsh Posté le 23-11-2009 à 15:57:56    

quand ca marchera je t'expliquerai le regexp

Reply

Marsh Posté le 24-11-2009 à 10:54:02    

T'es trop fort ca marche ;)
Milles merci !!!!!
 
Me reste une chose a faire et non des moindres mais avec ces explications je vais m'essayé tout seul ...
 
Mais pour te donner l'idée ... toujours dans ce meme fichier ... je dispose d'autre champ type :  

Code :
  1. [...]
  2. :1B:...
  3. :5K:/123456789
  4. ABC DEFGH
  5. ABCDEF GH
  6. :6A:...
  7. [...]

Et j'ai besoin de remplacer en gardant le retour chariot les valeurs situées dans la balises :5K: par ex par des "1" et "é". Cela donnera au final :

Code :
  1. [...]
  2. :1B:...
  3. :5K:/1111111111
  4. ééé ééééé
  5. éééééé éé
  6. :6A:...
  7. [...]

En tout cas merci je comprends un peu mieux le principe des chaines de caractères ;)
 
Cordialement


Message édité par Odissine le 24-11-2009 à 11:01:19
Reply

Marsh Posté le 25-11-2009 à 10:59:11    

OK alors je me suis essayé à le faire tout seul ...
 

Code :
  1. [...]
  2. ORIGINAL :
  3. :1B:...
  4. :5K:/123456789
  5. ABCDEFGH
  6. IJKLMNOP
  7. :6A:...
  8. [...]
  9. RESULTAT :
  10. [...]
  11. :1B:...
  12. :5K:/1111111111111111111
  13. éééééééééééééééé
  14. éééééééééééééééé
  15. ABCDEFGH
  16. IJKLMNOP
  17. :6A:...
  18. [...]
  19. MON BOUT DE CODE :
  20. $pat = "/(:50H:)(.*)(\n)/";
  21. $rep = ":50H:/1111111111111111111\néééééééééééééééé\néééééééééééééééé\n";
  22. $new = preg_replace($pat, $rep, $str);


 
J'y suis presque ;) en fait a chaque fin de ligne il y aun carriage return \n que je voudrais conserver ...
et l'idée est donc de vouloir remplacer les 1 à 3 lignes du champs 5K par des 111 et des ééé
 
Merci pour votre aide
 
Cdt

Reply

Marsh Posté le 25-11-2009 à 13:35:48    

c'est important l'espace avec les ééééééé ?
 
ABC DEFGH
ABCDEF GH

Reply

Marsh Posté le 25-11-2009 à 15:18:47    

non du tout ;)  
Mon but est tout simple...  
Balise contenu dans le fichier  
:AB:abcdefg
hijklmno
mnopqerts
:CD:
 
Je veux simplement remplacer le contenu de la balise :AB: par des /1111 pour la première ligne et des éééé pour les deux autres
C'est tout :s ...

Reply

Marsh Posté le 25-11-2009 à 16:20:42    

(\[...\]\s.+\s.+/)(\d+)(\s)(\w+[\s]?\w+)(\s)(\w+[\s]?\w+)(\s.+\s\[...])
 
et tu remplaces le groupe  
 
2, 4, 6
 
tu peux tester avec http://gskinner.com/RegExr/
 

Reply

Marsh Posté le 25-11-2009 à 16:36:53    

Rhaaa mais tu veux ma mort :p
 
J'ai du m'attaquer a un truc un peu trop lourd pour moi :( ....
 
Je pensais que ca serait plus simple ... :( ...

Code :
  1. {1:F01uuuuuuuuAXXX2269001727}{2:I101aaaaaaaaXXXXN}{4:
  2. :2A:TEST-MT OK
  3. :2B:00001/00001
  4. :5A:/40807840000001028230
  5. TEXTE 1
  6. TEXTE 2
  7. :5D:SOSOSOSO0
  8. :30:080410[...]
  9. -}
  10. Doit devenir :
  11. {1:F01uuuuuuuuAXXX2269001727}{2:I101aaaaaaaaXXXXN}{4:
  12. :2A:TEST-MT OK
  13. :2B:00001/00001
  14. :5A:/1111111111111111111
  15. ééééééééééééé
  16. ééééééééééééé
  17. :5D:SOSOSOSO0
  18. :30:080410[...]
  19. -}


 
Je suis un novice encore en terme de chaine de caractères ... étape par étape ;)
 
Merci en tout cas pour tout :) j'ai appris deux trois trucs déjà ;)

Reply

Marsh Posté le    

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.