Rechercher : dans
Par :

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

Dernière réponse le 19 jan 2007 à 16:55:44 efflamm, le 18 jan 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

Meilleures réponses pour « [PHP][manipulation a l'intérieur d'un chaine] » dans :
PHP - Nettoyer une chaîne de caractères Voir Voici une fonction en PHP qui peut être assez pratique, surtout quand on fait de l'URL Rewriting. Cette fonction permet de transformer les caractères de n'importe quelle chaîne de caractères en chaîne non accentuée, en enlevant les caractères...
PHP - Concaténation VoirPHP 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...
[PHP] Parse error, unexpected T_STRING, expecting ',' or ';' VoirCette 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 :
Les guillemets, apostrophes et les chaînes VoirComment jouer avec les guillemets et les apostrophes dans les chaînes 1. Préambule 2. Éviter une coupure dans la chaîne 3. Ajouter un guillemet dans la chaîne 3.1 Avec l'apostrophe 3.2 Avec l'ASCII 3.3 Directement 3.3.1 Méthode...
Langage C - Les chaînes de caractères VoirQu'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 chaîne...
Javascript - L'objet String VoirLes particularités de l'objet String string est un mot anglais qui signifie "chaîne", il s'agit en fait de chaîne de caractères. L'objet String est un objet qui contient un certain nombre de propriétés et de méthodes permettant la manipulation...
PHP - Expressions régulières VoirQu'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...

1

efflamm, le 19 jan 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 19 jan 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 19 jan 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 19 jan 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 19 jan 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 19 jan 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 19 jan 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 19 jan 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 19 jan 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