Flux rss
Collection CommentÇaMarche.net
Rechercher : dans
Par :

[PHP][manipulation a l'intérieur d'un chaine]

efflamm, le jeudi 18 janvier 2007 à 23:34:31 
 Signaler ce message aux modérateurs

Bonjour,
Je transfère des données d'un logiciel à un autre via un fichier texte que je fais parser par l'utilisateur via une adresse web locale d'un serveur linux debian (apache2,php4)

La moulinette qui "parse" le fichier lignepar ligne permet de "formater" les champs et d'enregistrer le nouveau fichier pour que l'autre logiciel veuille bien l'importer (le séparateur de champ est la virgule).

Une ligne type est représentée ainsi que suit :

champ1,champ2,champ3,champ4,champ5,etc,champ de la 7ième virgule,,,,champ11
et se termine par un retour à la ligne.

Je souhaite modifier une chaine après la 7ième virgule..Je n'y arrive vraiment pas.J'ai essayé à peu près tout ce que je sais faire en php.

Il me semble possible de le faire en alimentant une base SQL à partir de mon fichier texte, ainsi je pourrais balader mon "pointeur" dans le 7ième champ des lignes matchées et y faire ce que je veux. le volume d'information traitée etant faible( un fichier type comporte 200 lignes) je le ferais que si je n'ai pas d'autre choix.

Je pense qu'il est aussi possible de faire un appel system vers sed ou awk afin de traiter les lignes.je suis en train de regarder de ce coté là pour l'instant.

Il existe trés certainement d'autre solution dans d'autre langage, comme par exemple perl. Mais cela impliquerait de refaire complètement le script.Au cas ou quelqu'un aurais une solution dans un autre langage, c'est à ma portée de réécrire complètement le script.

Toute aide est la bienvenue, merci d'avance ;-)

Configuration: Windows XP
Internet Explorer 6.0

1

efflamm, le vendredi 19 janvier 2007 à 09:41:57
  • +1

J'ajoute la portion du code concerné.



// verif fichier de donnée
if(file_exists('import.txt'))
	{
	// on efface le précedent export
	if(file_exists('export.txt'))
     		{
          	unlink('export.txt');
     		}

	$FicEntree = fopen("import.txt", "r");
	$FicSortie = fopen("export.txt", "w+");
	echo '<br>Generation des lignes d\'ecritures<br>';

	while (!feof($FicEntree))
		{       $buffer = fgets($FicEntree, 4096);

	        $search = '"';
        	$replace = '';
        	$result0 = str_replace($search, $replace, $buffer);

	        $search = ',,';
        	$replace = ',';
        	$result1 = str_replace($search, $replace, $result0);

	        $search = 'VT,0';
        	$replace = 'VT,411000,';
        	$result2 = str_replace($search, $replace, $result1);

		$search = '707100,';
        	$replace = '707100,,';
        	$result3 = str_replace($search, $replace, $result2);

        	$search = '445710,';
        	$replace = '445710, ,';
        	$result4 = str_replace($search, $replace, $result3);

        	$search = '708500,';
        	$replace = "708500,,";
        	$result5 = str_replace($search, $replace, $result4);

        	$search = ',C';
        	$replace = '';
        	$result6 = str_replace($search, $replace, $result5);


		$mystring = $result5;
		$findme   = ',C';
		$pos = strpos($mystring, $findme);
		if ($pos === false)
        		{
			// etat inintéressant, la chaine n'est pas présente.
			// ce n'est pas fatal.
			}
		else
        		{
        		// ici je souhaite altérer la ligne courante , mais je ne sais pas comment m'y prendre.
		// je dois insérer une virgule après la 7ième virgule en partant de la gauche.
		// C'est ici mon problème
		        }
		// saut de ligne html	
		$search = ',EUR';
		$replace = ',EUR<br>';
		$result7 = str_replace($search, $replace, $result6);

		// on écrit les données dans le fichier de sortie sans la modif html
		fputs($FicSortie,$result6, 4096);
		// on affiche les données pour le navigateur
		echo $result7;
		}
	}
else
	{
   	echo '<br><font color=red size=3><center>ERREUR FATALE : Le fichier import.txt n\'existe pas</center></font><br>';
   	exit;
	}
echo 'Generation terminée<br>';
echo 'Fermeture des fichiers<br>';


fclose($FicEntree);
fclose($FicSortie);

Répondre à efflamm

2

Reivax962, le vendredi 19 janvier 2007 à 11:04:26

Bonjour,

La solution à ton problème passe par les expressions rationnelles.
Pour transformer la 7e virgule en deux virgules, utilise la fonction suivante :

$result6point5 = ereg_replace("(([^,]*,){7})(.*)", "\\1,\\3", $result6);

Pour l'explication : la fonction ereg_replace(string pattern, string replace, string cible) fait une recherche sur une chaine, d'après le paramètre pattern. Elle remplace ce pattern (motif, en Anglais) par ce qu'on lui donne en deuxième argument.

Le pattern que j'utilise est "(([^,]*,){7})(.*)"
On remarque 3 groupes parenthésés :
([^,]*,), que l'on va appeler \\2 (par convention de php, 2 parce que c'est la 2e parenthèse ouvrante)
(\\2{7}), que l'on va appeler \\1
et enfin
(.*), que l'on appelle \\3

Explication de chaque bloc.

\\1 signifie "\\2 est répété 7 fois".

\\2 signifie "tout sauf une virgule, répété indéfiniment, suivi d'une virgule. On reconnaît donc bien un bloc du style "abcdef,"

Donc, pour en revenir à \\1 , on comprend qu'on en arrive à la 7ème virgule.

\\3, lui, est tout simple : il signifie bêtement "n'importe quel caractère répété indéfiniment". C'est la fin de ta chaîne, qui n'a pas d'importance.

Ensuite, le deuxième argument, la chaine de remplacement.
C'est tout bête : je prends tout ce qu'il y a avant (soit "\\1"), je rajoute une virgule (c'est ce que tu veux faire, non ?), puis je colle derrière tout le reste, \\3. Ca donne bien "\\1,\\3".

Je t'invite à rechercher plus d'infos sur les expressions rationnelles sur le web, il doit y en avoir plein. (cherches aussi "expressions régulières", c'est une mauvaise traduction de l'anglais "regular expression", mais c'est très répendu...)

J'espère ne pas t'avoir trop embrouillé ^^

Xavier

Répondre à Reivax962

3

Reivax962, le vendredi 19 janvier 2007 à 11:07:08

Voilà, j'ai appliqué cette fonction à une chaine de test, et cela a donné :

$string_orig = "je, suis, une, chaine, avec, au, moins, sept, virgules, séparant, les, mots";
echo $string_orig;
$string_modif = ereg_replace("(([^,]*,){7})(.*)", "\\1,\\3", $string_orig);
echo "<br>".$string_modif;
Résultat :

je, suis, une, chaine, avec, au, moins, sept, virgules, séparant, les, mots
je, suis, une, chaine, avec, au, moins,, sept, virgules, séparant, les, mots

Répondre à Reivax962

4

efflamm, le vendredi 19 janvier 2007 à 11:10:51
  • +1

Wa !.. merci.
C'est la ou se voit la différence entre un amateur et un pro.
mille merci, j'intègre ça dès que j'en aurais le temps ce matin !

Répondre à efflamm

5

efflamm, le vendredi 19 janvier 2007 à 12:51:45

Ca marche mais..enfin pas tout à fait. Je m'explique en isolant 3 lignes types.
au départ on a ça :
1,011206,VT,0YYYY,,"XXXXXXXXX "," F061050", 3272.26,D,011206,EUR
2,011206,VT,707100,," XXXXXXXXX "," F061050", 2736.00,C,180107,EUR
3,011206,VT,445710,," XXXXXXXXX "," F061050", 536.26,C,180107,EUR

la moulinette l'écrit dans export.txt de la manière suivante :

1,011206,VT,411000,YYYY, XXXXXXXXXX , F061050, 3272.26,D,011206,EUR
2,011206,VT,707100,, XXXXXXXXX , F061050, 2736.00,C,180107,EUR
3,011206,VT,445710, , XXXXXXXXX, F061050, 536.26,C,180107,EUR

Jusque là tout va bien. Je sais que la fonction marche pris isolément sur une ligne ( verifié avec un echo de sa valeur).Si je tente d'exploiter son resultat , comme ici dans un str_replace et dans le cadre d'un if, c'est la cata totale.

$mystring = $result5;
$findme   = ',C';
$pos = strpos($mystring, $findme);
if ($pos === false)
        {}
else
        {
        $result6 = ereg_replace("(([^,]*,){7})(.*)", "\\1,\\3", $mystring);
        }
//$search = ',C';
//$replace = '';
//$result7 = str_replace($search, $replace, $result6);

$search = ',EUR';
$replace = ',EUR<br>';
$resulthtml = str_replace($search, $replace, $result6);

// on écrit les données dans le fichier de sortie sans la modif html
        fputs($FicSortie,$result6, 4096);
// on affiche les données pour le navigateur 

        echo $resulthtml;

Répondre à efflamm

6

efflamm, le vendredi 19 janvier 2007 à 13:50:58

Je continue à bosser dessus ^^ des choses doivent m'échapper.
----
j'ai avancé un peu. Je comprend mieux comment fonctionne ereg_replace. Nul besoin de l'utiliser dans un if {} else {}, seulement dans ce cas il modifie également les lignes que je ne souhaite pas. Cependant ça ne me sors pas des résultats certainement correct par rapport au code, mais pas du tout fidèle à ce que je veux. C'est donc un gros pas en avant.

S'il modifie aussi les lignes que je ne souhaite pas, je peux sans doute m'y adapter si je supprime ,D par exemple. Ca compenserait l'ajout d'un champ vide.je teste.
----
ce que je dis au dessus ne marche pas.
----

Répondre à efflamm

7

efflamm, le vendredi 19 janvier 2007 à 14:55:10
  • +1

Par contre ceci oui :

-------snip---------

$result5 = str_replace($search, $replace, $result4);
                $mystring = $result5;
                $findme   = ',C';
                $pos = strpos($mystring, $findme);
                if ($pos === false)
                        {$result6=$result5;}
                else
                        {
                        echo'<font color=red size=4>|</font>';
                        $result6 = ereg_replace("(([^,]*,){7})(.*)", "\\1,\\3", $mystring);
                        }
                $search = ',C';
                $replace = '';
                $result7 = str_replace($search, $replace, $result6);
                $search = ',EUR';
                $replace = ',EUR<br>';
                $resulthtml = str_replace($search, $replace, $result7);
                fputs($FicSortie,$result7, 4096);
                echo $resulthtml;
----snip----


le fameux etat pas intéressant dans ma boucle if plus haut , en fait il est interessant puisqu'il permet de dire à la boucle while (!feof()) ne touche pas à cette ligne. C'est ça qui m'échappais!
-----
J'ai des incohérences cependant , mais ça ne concerne plus ce problème précis.Voici :
Soit le morceau de ligne non parsée suivant
( ... ) VT,0YYYYYYY, ( ....)

D'après la moulinette ça devrait devenir

( .... ) VT,411000,YYYYY, ( ....)

Or voici ce qui arrive parfois seulement :

( ... ) VT,411000YYYYY, ( .....)

Cela arrive sur 3-4 lignes par fichier.Il y a surement une explication rationelle à ceci. Une particularité de la ligne, ou peut-etre que les fichiers sont hantés tout simplement.

En tout cas on peux considérerle problème principal comme résolu.Et pour être plus précis, c'est un transfert de comptabilité EBP gestion commerciale v9 vers SAGE v14.
Merci encore !

PS : le code complet, peut-etre servira t'il à quelqu'un ayant le meme problème.
<?php 
echo '<br>Initialisation du traitement ...<br>';
echo '<br>Les donnees seront sauvegardees dans : export.txt'; 
echo '<br>Ouverture des fichiers ...<br>';
echo '<br>Si une ligne ne parait pas conforme , verifiez toujours export.txt<br>';
// verif fichier de donnée
if(file_exists('import.txt')) 
	{ 
		if(file_exists('export.txt')) 
			{ 
          		unlink('export.txt'); 
     			} 
	$FicEntree = fopen("import.txt", "r");
	$FicSortie = fopen("export.txt", "w+");
	echo '<br>Generation des lignes d\'ecritures<br>';
	while (!feof($FicEntree)) 
		{	
		$buffer = fgets($FicEntree, 4096);
		$search = '"'; 
		$replace = ''; 
		$result0 = str_replace($search, $replace, $buffer);
		$search = ',,';
        	$replace = ',';
        	$result1 = str_replace($search, $replace, $result0);	
		$search = 'VT,0';
		$replace = 'VT,411000,'; 
		$result2 = str_replace($search, $replace, $result1); 
		$search = '707100,';
        	$replace = '707100,,';
        	$result3 = str_replace($search, $replace, $result2);
		$search = '445710,';
        	$replace = '445710, ,';
        	$result4 = str_replace($search, $replace, $result3);
		$search = '708500,';
        	$replace = "708500,,";
        	$result5 = str_replace($search, $replace, $result4);
		$mystring = $result5;
		$findme   = ',C';
		$pos = strpos($mystring, $findme);
		if ($pos === false) 
			{$result6=$result5;} 
		else 
			{
			$result6 = ereg_replace("(([^,]*,){7})(.*)", "\\1,\\3", $mystring);
			}
		$search = ',C';
		$replace = '';
		$result7 = str_replace($search, $replace, $result6);
		$search = ',EUR';
		$replace = ',EUR<br>';
		$resulthtml = str_replace($search, $replace, $result7);
		fputs($FicSortie,$result7, 4096);
		echo $resulthtml;
		}
	} 
else 
	{ 
   	echo '<br><font color=red size=3><center>ERREUR FATALE : Le fichier import.txt n\'existe pas</center></font><br>';	
   	exit;
	} 
echo 'Generation terminée<br>';
echo 'Fermeture des fichiers<br>';
fclose($FicEntree);
fclose($FicSortie);

?> 


Merci encore Xavier ;-)

Répondre à efflamm

8

efflamm, le vendredi 19 janvier 2007 à 16:02:51
  • +1

HMM :)
deux petites corrections.
ici

$findme   = ',C';
$pos = strpos($mystring, $findme);

Il convient de préciser que $findme = ',C,' ceci afin de ne pas matcher un autre champ que ,C,

et pour la même raison :
$search = ',C';
$replace = ' ';
$result7 = str_replace($search, $replace, $result6);

Il convient de préciser $search =',C,' et replace = ','

ceci élimine des petits problèmes.

Répondre à efflamm

9

 Ssylvainsab, le vendredi 19 janvier 2007 à 16:55:44

Salut.

Je n'ai pas lu tous le sujet (seulement les premiers messages), mais est-ce qu'un explode ne serait pas plus approprié ?
$champsArray=explode(',',meschamps);

a plus Sylvain
"Join us now, and share the software. You'll be Free, hackers."

Répondre à Ssylvainsab
PHP: Remplacer une chaîne dans un fichier php (Résolu) Bonjour, Je tente de créer un panneau d'administration permettant à un utilisateur de modifier certains paramètres d'un script. Pour ce faire, je cherche à remplacer dans un fichier PHP une chaîne de caractère par une autre via un script PHP. Voici ci... www.commentcamarche.net/forum/affich-4541834-php-remplacer-une-chaine-dans-un-fichier-php
Php, parcourir une chaine de caractère (Résolu) Bonjour, je cherche une fonction PHP qui parcoure une chaine de caractères et donne la valeur valeur d'un carctaière par son numéro dans la chaine. exemple $chaine = 'ABCD071'; je veux une fonction qui me donne la valeur du 4eme caractère le dans... www.commentcamarche.net/forum/affich-10315734-php-parcourir-une-chaine-de-caractere
Php + recuperer une chaine entre 2 balises (Résolu) Bonjour, Je cherche une fonction en PHP capable de renvoyé une chaine de caractere situé entre 2 balise dans une autre chaine. Exemple: Debutdetexte[MaBalise]TexteArecuperer/MaBalise2finDuTexte La fonction me permettrai de recuper TexteArecuperer... www.commentcamarche.net/forum/affich-4984610-php-recuperer-une-chaine-entre-2-balises
PHP - ConcaténationPHP permet de concaténer des chaînes de caractères grâce à l'opérateur "." : $concatenation= $a . $b; Ou encore pour affecter, dans la variable $a, la valeur de la concaténation de $a et de $b : $a.=$b; Pour concaténer des chaînes et des... www.commentcamarche.net/faq/sujet-16498-php-concatenation
[PHP] Parse error, unexpected T_STRING, expecting ',' or ';'Cette erreur, fréquente, se produit notamment lorsqu'un guillemet est présent dans une chaîne délimitée par ce même type de guillemets, par exemple : www.commentcamarche.net/faq/sujet-869-php-parse-error-unexpected-t-string-expecting-or
Vérifier le format d'une date en PHPIl existe plusieurs méthodes pour verifier le format d'une date en PHP, vous pouvez par exemple découper la chaîne puis tester les valeurs de chaque élément. Plus simplement nous utiliserons les expressions régulières. Pour valider une date au... www.commentcamarche.net/faq/sujet-9883-verifier-le-format-d-une-date-en-php
[PHP] couper une chaine => tableau (Résolu)Bonjour, j'ai un ptit soucis. je veux faire une fonction php: Au depard j'ai une chaine de caractère du style: "font:ariblk.ttf;fontSize:12;colorText:FF0000;colorBg:FFFFFF;" et j'aimerias qu'a la fin de la fonction j'ai un tableau du style:... www.commentcamarche.net/forum/affich-3375007-php-couper-une-chaine-tableau
Manipulation de chaine de caractere en pl/sql (Résolu)Bonjour tous le monde , SVP j'ai un sujet a préparer sur les fonctions de manipulation des chaines de caractère en pl/sql + des fonctions et procédures et je suis totalement bouleverser puisque je suis nouveau en ce module. SVP que quelqu'un m'aide et... www.commentcamarche.net/forum/affich-8779344-manipulation-de-chaine-de-caractere-en-pl-sql
Pb PHP, decouper un chaine par caractere (Résolu)Bjr, J'ai un petit probléme en PHP, je recois en parametre d'une fonction une mot. je voudrai placé chaque caractère de ce mot dans une case d' un tableau. connaiser vous une fonction qui permet de faire ceci ou une astuce de prog. merci www.commentcamarche.net/forum/affich-1549513-pb-php-decouper-un-chaine-par-caractere
Les chaînes de caractères en C++Qu'est-ce qu'une chaîne de caractères ? Une chaîne de caractères (appelée string en anglais) est une suite de caractères, c'est-à-dire un ensemble de symboles faisant partie du jeu de caractères, défini par le code ASCII. En langage C++, une... www.commentcamarche.net/contents/cpp/cppstring.php3
PHP - Expressions régulièresQu'est-ce qu'une expression régulière? Les expressions régulières sont des modèles créés à l'aide de caractères ASCII permettant de manipuler des chaînes de caractères, c'est-à-dire permettant de trouver les portions de la chaîne correspondant au... www.commentcamarche.net/contents/php/phpreg.php3
PHP - Les fichiersLa gestion des fichiers avec PHP Avec PHP, la création ou la lecture de fichiers est, une fois de plus, assez simple. Il existe une multitude de fonctions dédiées à l'utilisation des fichiers. La communication entre le script PHP et le fichier... www.commentcamarche.net/contents/php/phpfich.php3