[PHP][formattage de texte]

Résolu/Fermé
efflamm - 19 déc. 2007 à 16:24
 efflamm - 20 déc. 2007 à 02:08
Bonjour,

Le contexte :
Un script php parse ligne par ligne un fichier texte et effectue divers formattage sur ces lignes, puis retourne un affichage html propre. Dans le meme temps il crée un nouveau fichier texte avec le bon formattage.

la plateforme:
Apache/2.0.55 (Debian) PHP/5.1.6-1

le texte rendu après passage à la moulinette en l'état d'avancement du script :

081207, TA550,UN_NOM,D, 454.48,                     // debut d'une nouvelle ligne avec un nom
C, 380.00,141207,                  // une ligne à reporter sur la ligne précédente
C, 74.48,141207,                    // une 2ième
081207, TA551,UN_AUTRE_NOM,D, 5502.37,                  // début d'une nouvelle ligne avec un nom
C, 4400.00,141207,               // une ligne
C, 200.64,141207,                 // deux lignes
C, 901.73,141207,                 // trois 
081207, TA552,,D, 5262.40,                                          // ici c'est bien un nouvelle ligne mais il y a un manque de donnée ( le nom)
                                                                                          // il faut faire avec, le facteur isolant n'est pas le nom mais un code que je              
                                                                                         //n'affiche pas mais qui est uniquement présent sur les lignes ou il est censé         
                                                                                         //y avoir un nom.
C, 4400.00,141207,              // une ligne
C, 862.40,141207,                // deux 


la problématique:
Je ne suis qu'un amateur en programmation je bloque sur un dernier point.Je souhaiterais que le texte rendu fini ressemble à ceci :

081207, TA550,AAAAAAZZYYYX,D, 454.48,C, 380.00,141207,C, 74.48,141207,
081207, TA551,BBBBBBBBBBBBCCD,D, 5502.37,C, 4400.00,141207,C, 200.64,141207,C, 901.73,141207,
081207, TA552,,D, 5262.40,C, 4400.00,141207,C, 862.40,141207,


Au début je pensais passer par MySQL histoire de pouvoir choisir plus aisément "quel champs va ou".Finalement je me suis rendu compte que la fonction explode fait l'affaire, du moins pour en arriver au point que je souhaitais : c'est à dire stocker dans un tableau les données des lignes afin de choisir quoi afficher en fonction de mon souhait.Puis d'isoler certaine ligne en fonction de particularité présente pour les traiter différement.Sauf qu'après pour le formattage ça se corse , je ne sais pas comment concaténer les lignes qui suivent une ligne principale.Evidemment je ne peux pas compter les virgules. Par contre il y a un délimiteur exploitable "VT,411000," qui est toujours à la meme place sur les lignes principales.Toute aide est la bienvenue et pardon d'avance pour mon style trés bourrin..

code concerné:
<html>
<head>
<title></title>
<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
</head>
<body>

<?php
// des politesses

if(isset($_POST['name_file_import']))      $name_file_import=$_POST['name_file_import'];
else      $name_file_import="import.txt";
if(isset($_POST['name_file_export']))      $name_file_export=$_POST['name_file_export'];
else      $name_file_export="export_autre.txt";

if(empty($name_file_import) OR empty($name_file_export))
    {
     echo '<html><table border width=90% height=90%% bgcolor=#EEFFFF align=center>';
     echo '<tr><th><br><center><font color=green size=3>Ouverture et verification des fichiers ...</font>';
     echo '<font color=red size=5><center><b>ATTENTION LES DEUX CHAMPS DOIVENT ETRE RENSEIGNES !<br></font>';
     echo '<input type="button" value="Précédent" onclick="history.back();"><center></th></tr></table></html>';
     exit;
    }
// Aucun champ vital n'est vide, on peut continuer

else
    {
        $pattern = '[`/\*$% ]'; //Définition de l'ensemble des caractères refusés
        if(eregi($pattern,$name_file_import) OR eregi($pattern,$name_file_export))
        {
        echo '<html><table border width=90% height=90%% bgcolor=#EEFFFF align=center>';
        echo '<tr><th><br><center><font color=green size=3>Ouverture et verification des fichiers ...</font>';
        echo '<br><font color=red size=5><center><b>ERREUR !<br>';
        echo "UN CARACTERE NON AUTORISE A ETE SAISI ! <br>VERIFIEZ LE NOM !</b></center></font><br>";
        echo '<input type="button" value="Précédent" onclick="history.back();"><center></th></tr></table></html>';
        exit;
        }
        else {
// verif des fichiers
if(file_exists($name_file_import))
        {
        if(file_exists($name_file_export))
                {
                unlink($name_file_export); // on efface
                }
        $FicEntree = fopen($name_file_import, "r"); // on ouvre les E/S
 $FicSortie = fopen($name_file_export, "w+");
        echo '<br><font color=green size=3>Génération des lignes d\'ecritures :</font><br><hr>';
        while (!feof($FicEntree)) // on parse ligne par ligne
                {
                $buffer = fgets($FicEntree, 4096); // longueur de ligne max 4ko

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


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

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

                $mystring=$result2;
                $findme='VT,411000,'; // ici on altère les lignes contenant 2 particularités 
                $pos = strpos($mystring, $findme);
                if ($pos === false)
                        //chaine non trouvée on altère rien
                        {$result3=$result2;}
                else
                        {
                        //chaine trouvée
                        $nbrvirgule = substr_count ($result2, $search);
                        if ($nbrvirgule = 11)
                                {
                                //il y a 11 virgules ici donc un champ de trop, on altère
                                $search=',,';
                                $replace=',';
                                $result3=str_replace($search, $replace, $result2);
                                }
                        else
                                {
                                //nada, on altère pas
                                 $result3=$result2;
                                }
                        }

                // segmentation en vue d'un formattage particulier

                $data = explode(",", $result3);
                for ($i = 6; $i <= 9; $i++)
                        {
                        $findme = 'VT,411000,';
                        $pos = strpos($result3,$findme);
                        if ($pos === false)
                                {
                                echo str_replace(CHR(13),"",$data[$i+2]).",";
                                echo str_replace(CHR(13),"",$data[$i+1]).",";
                                echo str_replace(CHR(13),"",$data[$i+3]).",";
                                }
                        else
                                {
                                echo str_replace(CHR(13),"",$data[$i+3]).",";
                                echo str_replace(CHR(13),"",$data[$i]).",";
                                echo str_replace(CHR(13),"",$data[$i-2]).",";
                                echo str_replace(CHR(13),"",$data[$i+2]).",";
                                echo str_replace(CHR(13),"",$data[$i+1]).",";
                                }
                        $i=9;
                      //  echo"<br>";
                        }

                }
        }
else
        {
        echo '<html><table border width=90% height=90%% bgcolor=#EEFFFF align=center>';
        echo '<tr><th><br><center><font color=green size=3>Ouverture et verification des fichiers ...</font>';
        echo '<br><font color=red size=5><center><b>ERREUR !<br>';
        echo "LE FICHIER $name_file_import EST INEXISTANT ! <br>VERIFIEZ LE NOM !</b></center></font><br>";
        echo '<input type="button" value="Précédent" onclick="history.back();"><center></th></tr></table></html>';
        exit;
        }
echo '<hr><font color=green size=3>Generation terminée</font><br>';
echo '<br><font color=green size=3>Fermeture des fichiers</font><br>';
//on ferme E/S
fclose($FicEntree);
fclose($FicSortie);
}
}
?>
</body>
</html>
A voir également:

7 réponses

Heu.. c'est lorsque on arrête 5 mins qu'on commence à voire certaine choses qu'on a sous les yeux depuis des heures, Il y a aussi les ,C, qui peuvent servir de délimiteur avec peut-être une logique du genre " tant que ,C, est trouvée concatène la ligne entière avec la précédente ainsi de suite jusqu'a ce qu'il n'y ai plus de ,C, puis reprend l'execution normale du script".. pêut-être une piste.
0
Toujours pas de solution qui marche pour joindre les lignes ensembles, mais j'avance un peu dans d'autre partie.


// segmentation
                $result4=preg_replace('/\s{2,}/', ' ', $result3); // on vire les espaces
                $data = explode(",",$result4); // on segmente
                for ($i = 6; $i <= 9; $i++)
                        {
                        $findme = 'VT,411000,';
                        $pos = strpos($result4,$findme);
                        if ($pos === false)
                                {
                                echo $data[$i+2].","; // juste un affichage
                                echo $data[$i+1].",";
                                echo $data[$i+3].",";
                                fputs($FicSortie,$data[$i+2].",", 4096); // on écrit dans le fichier de sortie
                                fputs($FicSortie,$data[$i+1].",", 4096);
                                fputs($FicSortie,$data[$i+3].",", 4096);

                                }
                        else
                                {
                                echo $data[$i+3].",";
                                echo $data[$i].",";
                                echo $data[$i-2].",";
                                echo $data[$i+2].",";
                                echo $data[$i+1].",";
                                fputs($FicSortie,$data[$i+3].",", 4096);
                                fputs($FicSortie,$data[$i].",", 4096);
                                fputs($FicSortie,$data[$i-2].",", 4096);
                                fputs($FicSortie,$data[$i+2].",", 4096);
                                fputs($FicSortie,$data[$i+1].",", 4096);

                                }
                        $i=9;
                        echo"<br>";
                        fputs($FicSortie,"\n", 4096);
                        }
0
plus propre, et surtout j'ai pigé le . pour de bon


    echo $data[$i+2].",".$data[$i+1].",".$data[$i+3].","; // juste un affichage
                                fputs($FicSortie,$data[$i+2].",".$data[$i+1].",".$data[$i+3].",",4096); // on écrit

                                }
                        else
                                {
                                echo $data[$i+3].",".$data[$i].",".$data[$i-2].",".$data[$i+2].",".$data[$i+1].",";
                                fputs($FicSortie,$data[$i+3].",".$data[$i].",".$data[$i-2].",".$data[$i+2].",".$data[$i+1].",", 4096);
                                }
0
Sinon en passant par le shell avec sed ou awk directement à partir du txt généré, sinon je vois pas comment joindre des lignes en php,je trouve un tas de ressources sur le net mais aucune ne fait l'affaire.
sos ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bonsoir,

j'ai remarqué que toutes tes lignes que tu dois garder au debut du futur fichier sortie commencent par 081207, les autres commencent par une lettre.

Même si cette date change, on peut tester si ligne commence par 6 chiffres.

Alors inspires toi de ça:

$array_fichierE=file('fichier.txt');// on lit le fichier et il est mis dans un array (tableau) ligne par ligne
$RE="#^[0-9]{6}$#";// definition de la regle pour tester 081207 par exemple ( 6 chiffres et seulement 6)
$num=-1; //init du compteur index ligne fichier final a -1 car au premier coup on rajoutera 1 donc => 0
$array_fichierS=array(); // init nom fichier sortie
foreach($array_fichierE as $ligne){
	$array_ligne=explode("'",$ligne); // on eclate la ligne dans un array
	//on teste si commence par 6 chiffres
	if (preg_match($RE,$array_ligne[0])){
			// si le premier element est un nombre de 6 chiffres
			$num++; //on incremente le numero future ligne seulement dans ce cas
			$chaine_ligne=implode(",",$array_ligne); //on remet la ligne comme avant
			$array_fichierS[$num]=$chaine_ligne
	}else{
			// si le premier element n'est pas un nombre de 6 chiffres
		$chaine_ligne=implode(",",$array_ligne); //on remet la ligne comme avant
		$array_fichierS[$num].=",";//on rajoute une virgule entre
		$array_fichierS[$num].=$chaine_ligne; //on empile à la suite
	}
}


$FicSortie = fopen($name_file_export, "w+");
// on ecrit le fichier sortie ligne par ligne
foreach($array_fichierS as $ligne){
	fputs($FicSortie,$ligne);

}
fclose();
0
Merci pour la réponse, vraiment !
J'ai trouvé une méthode, bête et bourrin, mais bon ça marche.. cela ne va pas m'empecher d'essayer la tienne qui semble nettement plus propre ;-)

for ($i = 6; $i <= 9; $i++)
                        {
                        $findme = 'VT,411000,';
                        $pos = strpos($result4,$findme);
                        if ($pos === false)
                                {
                                $c=$c+1;
                                $sortie=$data[$i+2].",".$data[$i+1].",".$data[$i+3].",";
                                echo $sortie; // juste un affichage
                                fputs($FicSortie,$sortie,4096); // on écrit
                                }
                        else
                                {
                                if ($c===4){echo "<br>";fputs($FicSortie,"\n", 4096);}
                                elseif ($c===3){echo "<br>";fputs($FicSortie,"\n", 4096);}
                                elseif ($c===2){echo "<br>";fputs($FicSortie,"\n", 4096);}
                                $c=0;
                                $sortie2=$data[$i+3].",".$data[$i].",".$data[$i-2].",".$data[$i+2].",".$data[$i+1].",";
                                $temp=preg_replace("/(\r\n|\n|\r)/", " ", $sortie2);
                                echo $temp;
                                fputs($FicSortie,$temp, 4096);
                                }
                        $i=9;
                        }
                }
0
j'ai oublié de commenter =/.

J'ai effectivement joué avec un incrément mais sur les ,C, en début de ligne puis envoyer un retour à la ligne en fonction du compteur. je l'ai pas tourné dans tout les sens mais ça marche jusqu'a 4, si un jour une 5ième ligne viens jouer les troubles fêtes il va falloir modifier le code. Ce à quoi la solution d'Alain42 ne semble pas vulnérable, et c'est trés judicieux d'avoir remarqué pour la date.C'était sous mon nez depuis trop de temps surement pour que je le vois ;-)

Objectif présent : virer mon code tout pourri et utiliser celui d'Alain42
0