fgetcsv ändern anderes Trennzeichen

Dolphon

Erfahrenes Mitglied
Hi,

folgende DAtei wurde bis jetzt z.B von meinem Skript eingelesen:

Code:
"Feld1","Feld2","Feld3","Feld4"
"Data1","Data2: String="xyz" fertig","Data3","Data4"
"Data1","Data2: String="xyz" fertig","Data3","Data4"

Nun hat sich an dem Feldinhalt aber etwas geändert. Nun sollen auch Kommas im Feldinhalt vorkommen. Somit kann ich das Komma, welches ich bis dato als Trennzeichen genutzt habe, nicht mehr verwendet werden. Stattdessen will ich nun "," als Trennzeichen benutzen.
Leider kann ich dies mit fgetcsv nicht realisieren.

Hier der Code des bisherigen Skriptes:

DAS FGETCSV IN DER WHILE SCHLEIFE IST DAS PROBLEM

PHP:
$fh = fopen($argv[3], "r") or die ("cannot open file ".$argv[3]."\n"); #File in ein Array einlesen

//Anzahl der Zeilen ermittlen
$zeilen = 0;
if ($fh) {
  while (!feof($fh)) {
    if (fgets($fh,1048576)) {
      $zeilen++;
    }
  }
}
rewind($fh);

$felder = fgetcsv($fh, 1000, ",");    // Feldnamen ermitteln
$anzahl = count($felder);            // Anzahl der Felder speichern

#Bei den Parametern der fgetcsv-Anweisung wird "~" als das Zeichen angegeben in welches der Text eingeschlossen ist. 
#Es sollte/müßte ein Zeichen sein, das in Wirklichkeit nicht in der Datei enthalten ist.
#Das hat zur Folge, dass das doppelte Anführungszeichen beim Einlesen nicht entfernt wird.
$i=0;
$resultfile=fopen("konvertiert_zu_line.".$i.".txt","w");
while ($inhalt = fgetcsv($fh, 1000, ",", "~")) {
    for ($a = 0; $a < $anzahl; $a++) {
        fputs($resultfile,$felder[$a] .";" .trim($inhalt[$a],"\"") ."\r\n");
    }
    fputs($resultfile,"\r\n");
	$i++;
	if($i<$zeilen-1)
	{
	fclose($resultfile);
	$resultfile=fopen("konvertiert_zu_line.".$i.".txt","w");
	}
} 

		echo "Konvertierung erfolgreich";
		unset($fh);


Noch zur Erläuterung.
Für jede Datenzeile wird eine neue Datei in Liniendarstellung erstellt.
 
Du müsstest den enclosure richtig verwenden (" angeben) und wenn du unbedingt die Anführungsstriche im String haben willst, so müsste man die nachträglich hinzufügen.
 
So sollte es klappen:

fgetcsv($fh, 1000, ",", "\"")

Wenn Du in einem Feld das Anführungszeichen verwenden willst, einfach vorher verdoppeln: preg_replace("/[\"]/","\"\"",$_text);
 
Zuletzt bearbeitet:
@xanthos
Ich hab es einmal so gemacht, wie du es vorgeschlagen hast:

PHP:
while ($inhalt = fgetcsv($fh, 1000, $trennzeicheneingabe, "\"")) {
    for ($a = 0; $a < $anzahl; $a++) {
        fputs($resultfile,$felder[$a] .$trennzeichenausgabe .trim($inhalt[$a],"\"") ."\r\n");
    }
    fputs($resultfile,"\r\n");
	$i++;
	if($i<$zeilen-1)
	{
	fclose($resultfile);
	$resultfile=fopen("konvertiert_zu_line.".$i.".txt","w");
	}
}

Mit dem " verdoppeln, habe ich so meine SChwierigkeiten.
Wenn ich ganz am Anfang die einzulesende Datei neuschreibe:

PHP:
$text = file_get_contents($argv[3]);
$text = preg_replace("/[\"]/","\"\"",$text);
$handle = fopen($argv[3],"w");
fwrite($handle, $text);

Dann habe ich in der Ausgabe nachher zu viele ".

Code:
Feld1"";Data1
Feld2"";Data2: 
Feld3"";String=""xyz"" fertig
Feld4"";Data3
 
Du musst die Anführungszeichen auch nur IM Feld verdoppeln. Z.B.:

"Feld 1","das ist der ""Inhalt"" ...","...","..."

Wenn Du diese Zeile nun mit fgetcsv($fh, 1000, ",", "\"") einliest, erhältst Du folgendes Array:

Array(
[0] => Feld 1
[1] => das ist der "Inhalt" ...
[2] => ...
[3] => ...
[4] => ...
)
 
Sry, aber irgendwie bekomm ich das nicht.

PHP:
while ($inhalt = preg_replace("/[\"]/","\"\"",fgetcsv($fh, 1000, $trennzeicheneingabe, "\""))) {

ergibt bei mir

Code:
Feld1;Data1
Feld2;Data2: ,String=xyz"" fertig
Feld3;Data3
Feld4;Data4
 
Zuletzt bearbeitet:
Ich habe das mit den doppelten Anführungszeichen nun so gelöst.
Ist zwar wahrscheinlich nicht gerade schön, aber es funktioniert.
Wenn einer eine kurzere Variante hat, darf er diese gerne posten.

PHP:
$trennzeicheneingabe = $argv[1];
$trennzeichenausgabe = $argv[2];

//-----------CSV DAtei neu erstellen und Ermittlung Anzahl der Zeilen wegen inneren Anführungszeichen
$fh = fopen($argv[3], "r") or die ("cannot open file ".$argv[3]."\n"); #File in ein Array einlesen
$fh2 = fopen($argv[3]."neu", "a")or die ("cannot write file ".$argv[3]."neu\n");

$zeilen = 0;
if ($fh) {
  while (!feof($fh)) {
  $bingo = fgets($fh,1048576);
    if ($bingo) 
	{
	
	$felder = ereg_replace("\",","',",$bingo);
	$felder = ereg_replace(",\"",",'",$felder);
	$felder = str_replace(array("\r", "\n"), '', $felder);
	$felder = substr_replace($felder,"'",0,1);
	$felder = substr_replace($felder,"'",strlen($felder)-1);
	$felder = preg_replace("/[\"]/","\"\"",$felder);
	$felder = $felder."\r\n";
	$felder = ereg_replace("',","\",",$felder);
	$felder = ereg_replace(",'",",\"",$felder);
	$felder = ereg_replace("'","\"",$felder);
	$zeilen++;
	//echo $felder;
	fwrite($fh2, $felder); 
    }
  } 
}

//---------------------------------

fclose ($fh);
fclose ($fh2);
$fh3 = fopen($argv[3]."neu", "r")or die ("cannot write file ".$argv[3]."neu\n");

$felder = fgetcsv($fh3, 1000, $trennzeicheneingabe);    // Feldnamen ermitteln
$anzahl = count($felder);            // Anzahl der Felder speichern


$i=0;
$resultfile=fopen("konvertiert_zu_line_".$i.".txt","w");


while ($inhalt = fgetcsv($fh3, 1000, $trennzeicheneingabe, "\"")) {
    for ($a = 0; $a < $anzahl; $a++) {
		fputs($resultfile,$felder[$a] .$trennzeichenausgabe .trim($inhalt[$a],"\"") ."\r\n");
    }
    fputs($resultfile,"\r\n");
    $i++;
    if($i<$zeilen-1)
    {
    fclose($resultfile);
    $resultfile=fopen("konvertiert_zu_line_".$i.".txt","w");
    }
} 

		echo "Konvertierung erfolgreich";
 
Die CSV Datei welche übergeben wird sieht so aus:

Code:
"Feld1","Feld2","Feld3","Feld4"
"Data1","Data2: , String="xyz" fertig","Data3","Data4"
"Data1","Data2: String="xyz" fertig","Data3","Data4"

Der ersteTeil des Skriptes erstellte diese Datei neu mit den doppelten Anführungszeichen im inneren Teil:

Code:
"Feld1","Feld2","Feld3","Feld4"
"Data1","Data2: , String=""xyz"" fertig","Data3","Data4"
"Data1","Data2: String=""xyz"" fertig","Data3","Data4"
 
Versuche das:

PHP:
<?php
  $_csv_old = 'csv_alt.csv';
  $_csv_new = 'csv_neu.csv';

  $_open_old = fopen($_csv_old,'r');
  $_open_new = fopen($_csv_new,'w');
  while($_line = fgets($_open_old,10000)){
  
    $_line = preg_replace('/(?<!^|\,)\"(?!$|\,)/','""',$_line);
    fputs($_open_new,$_line."\n");
  
  }
  fclose($_open_old);
  fclose($_open_new);
?>

Solange innerhalb der Felder keine ," oder ", Kombination vorkommt, sollte es keine Probleme geben ;)
 
Zuletzt bearbeitet:
Zurück