Reguläre Ausdrücke
Hias
- php
Hallo,
ich probiere mittlerweile seit Stunden herum um einen Text in einer CSV Datei zu ersetzen. Ich habe folgendes Problem: Ich muss eine Konvertierung von CSV in XML realisieren. Die Daten stammen aus einer DB und dort wurden bei der Telefonnummer folgende Datensätze unter Telefonnummer eingefügt (inkl. Anführungszeichen): "12354.... ; Fax: 01234"
Das Problem ist das Semikolon zwischen den Anführungszeichen, denn dadurch würden bei der Konvertierung in XML die Datensätze verschoben werden, weil zuviele Semikolons in einem Datensatz, der aus dutzenden Daten besteht, vorhanden sind.
Bildlich gesprochen soll die XML Datei so aussehen:
<datensatz>
<ktonr>65564</ktonr>
...
<tel>01523 fax 15654 festnetz 45623</tel> // Ohne Semikolon
...
</datensatz>
Im Moment sieht es bei den ersten paar hundert Datensätzen genau so aus. Sobald Telefonnummer, Fax Nummer usw. im selben Feld, getrennt durch Semikolon, eingegeben wurde, würde bei der Konvertierung ab diesem Zeitpunkt die <ktonr> zum Beispiel leer sein oder ein Name oder irgendwas, aber nicht die Kontonummer, weil sich das ganze verschiebt.
Deshalb möchte ich mit preg_replace nach dem Suchtext (inkl. Anführungszeichen)
"nummer ; nummer"
suchen und das Semikolon entfernen
Ich habe mich selbst erst in die Thematik reguläre Ausdrücke eingelesen, leider bin ich jetzt mit meinem Latein am Ende und bitte euch um Hilfe.
mfg
Hi!
Die Daten stammen aus einer DB und dort wurden bei der Telefonnummer folgende Datensätze unter Telefonnummer eingefügt (inkl. Anführungszeichen): "12354.... ; Fax: 01234" Das Problem ist das Semikolon zwischen den Anführungszeichen, denn dadurch würden bei der Konvertierung in XML die Datensätze verschoben werden, weil zuviele Semikolons in einem Datensatz, der aus dutzenden Daten besteht, vorhanden sind.
Nein, das ist kein Problem, denn die Anführungszeichen verhindern, dass Semikolon und Zeilenumbruch als Daten(satz)trenner betrachtet werden. Funktionen wie fgetcsv() erkennen solche Situationen korrekt.
Deshalb möchte ich mit preg_replace nach dem Suchtext (inkl. Anführungszeichen)
"nummer ; nummer"
suchen und das Semikolon entfernen
Ich habe mich selbst erst in die Thematik reguläre Ausdrücke eingelesen, leider bin ich jetzt mit meinem Latein am Ende und bitte euch um Hilfe.
Was ist denn das genaue Problem, auf das du gestoßen bist? Hast du die Sonderbehandlung von Zeilenumbrüchen beachtet, die man mittels eines Modifizierers (modifier) ändern kann?
Lo!
Danke für deine schnelle Antwort.
Nein, das ist kein Problem, denn die Anführungszeichen verhindern, dass Semikolon und Zeilenumbruch als Daten(satz)trenner betrachtet werden. Funktionen wie fgetcsv() erkennen solche Situationen korrekt.
»»
»»
Okay, das wusste ich nicht. Ich habe mit explode gearbeitet, nicht mit fgetcsv.
»»
Was ist denn das genaue Problem, auf das du gestoßen bist? Hast du die Sonderbehandlung von Zeilenumbrüchen beachtet, die man mittels eines Modifizierers (modifier) ändern kann?
Ich habe keine Zeilenumbrüche mehr, da ich sie entfernt habe.
Kleines Beispiel aus der modifizierten csv Datei:
;"0044... ; fax ...2";
Nachdem ich mit explode gearbeitet habe, sieht meine XML so aus:
<tel>0044...</tel>
<bankleitzahl>fax ...2</blz>
Mein konkretes Problem ist, dass ich das Semikolon zwischen den Anführungszeichen nicht ansprechen kann.
Meiner Meinung nach bin ich mit dem Befehl/Suchmuster preg_replace('#"(.*);(.*)"#',' ', $dat);
sehr nahe dran, aber leider entfernt er das Semikolon nicht.
mfg
Hallo,
Meiner Meinung nach bin ich mit dem Befehl/Suchmuster preg_replace('#"(.*);(.*)"#',' ', $dat);
sehr nahe dran, aber leider entfernt er das Semikolon nicht.
Das würde eventuell sogar funktionieren, Du ersetzt aber das komplette Pattern durch Leerzeichen (nicht nur das Semikolon). Du möchtest ja das was vor und nach dem Semikolon steht erhalten.
Ich denke etwas wie
preg_replace('#"(.*?);(.*?)"#','#"\\1 \\2"#', $dat);
müsste klappen.
Hi!
Mein konkretes Problem ist, dass ich das Semikolon zwischen den Anführungszeichen nicht ansprechen kann.
Brauchst du ja jetzt auch nicht mehr, denn fgetcsv() macht das ja ganz hervorrangend, ohne dass du sämtliche CSV-Regeln mit RegExp nachbilden musst. Die nächste wäre nämlich, "" innherhalb von mit " eingerahmten Werten als einfaches " zu interpretieren.
Lo!
Hi!
Mein konkretes Problem ist, dass ich das Semikolon zwischen den Anführungszeichen nicht ansprechen kann.
Brauchst du ja jetzt auch nicht mehr, denn fgetcsv() macht das ja ganz hervorrangend, ohne dass du sämtliche CSV-Regeln mit RegExp nachbilden musst. Die nächste wäre nämlich, "" innherhalb von mit " eingerahmten Werten als einfaches " zu interpretieren.
Lo!
Hmm... Also umschreiben bleibt nur die letzte Notlösung - mein ganzes Skript umfasst mehrere Tage Arbeit. Jetzt probiere ich noch mit ersetzen. Das Ziel ist in ergreifender Nähe...
Trotzdem Danke! ;)
Hi,
Brauchst du ja jetzt auch nicht mehr, denn fgetcsv() macht das ja ganz hervorrangend
Hmm... Also umschreiben bleibt nur die letzte Notlösung
Nein, es ist die einzig vernünftige Lösung.
- mein ganzes Skript umfasst mehrere Tage Arbeit.
Dann nimm als Lerneffekt daraus mit, dass du dich nächstes mal *vorher* informierst, welche fertigen Funktionen es für eine Aufgabe schon gibt, bevor du anfängst, irgendwas selber zu basteln.
Jetzt probiere ich noch mit ersetzen. Das Ziel ist in ergreifender Nähe...
Die Gefahr, dass du dabei irgendeine Sonderkonstellation übersiehst bzw. nicht abdeckst, ist groß.
MfG ChrisB
Brauchst du ja jetzt auch nicht mehr, denn fgetcsv() macht das ja ganz hervorrangend
Ja? Ich finde diese Funktion komplett überflüssig! Unzählige male habe ich es damit probiert und es klappt nicht.
$csv=fopen("csvdatei.csv","r");
while ( ($data=fgetcsv($csv,2000,";")) !=FALSE)
{
echo $csv;
}
#3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id..............
Also ich kann mit der Funktion nichts anfangen!
Hi,
Brauchst du ja jetzt auch nicht mehr, denn fgetcsv() macht das ja ganz hervorrangend
Ja? Ich finde diese Funktion komplett überflüssig! Unzählige male habe ich es damit probiert und es klappt nicht.
Das liegt an dir, nicht an der Funktion.
$csv=fopen("csvdatei.csv","r");
while ( ($data=fgetcsv($csv,2000,";")) !=FALSE) { echo $csv; }
>
> #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id #3Resource id..............
Warum interessiert dich eigentlich das Ergebnis des Aufrufes von fgetcsv, das du in $data ablegst, in deiner Schleife gar nicht?
Und warum hast du andererseits bei jedem Schleifendurchlauf ein erneutes Interesse daran, zu überprüfen, ob das Öffnen der Datei zum lesen geklappt hat?
> Also ich kann mit der Funktion nichts anfangen!
Merkt man. Beschäftige dich mit Grundlagen.
MfG ChrisB
--
RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
Moin!
Hier packst du das Ergebnis von fgetcsv() in die Variable $data:
while ( ($data=fgetcsv($csv,2000,";")) !=FALSE)
Und dann lässt du dir diese Variable in der Schleife ausgeben:
echo $csv;
Ähm... doch nicht. $data wäre gut, $csv ist die File-Ressource der geöffneten Datei.
Beachte, dass $data ein Array ist. echo $data liefert dir auch nur fortlaufend "Array" als Ausgabe.
Also ich kann mit der Funktion nichts anfangen!
Die Konvertierung einer CSV-Datei in passendes XML ist aus meiner Sicht eine Sache von vielleicht sechs Zeilen Code.
- Sven Rautenberg
Hallo,
So lange immer maximal ein Semikolon in den Anführungszeichen vorkommt, könntest Du es so probieren:
$newStr = preg_replace ("/\"([^\"]*?);([^\"]*?)\"/" , "\"\\1 \\2\"" , $csvString);
(habs nicht ausprobiert, müsstest mal testen).
Lies (die " sind immer maskiert, da sie ja Teil eines PHP-Strings sind):
"Suche alles, was mit " anfängt
gefolgt von beliebig viel oder gar nichts (*?) was kein " ist ([^"])
gefolgt von einem Semikolon
gefolgt von beliebig viel oder gar nichts (*?) was kein " ist ([^"])
gefolgt von "
UND ERSETZE DIES DURCH
"(das was vor dem Semikolon steht) (das was nach dem Semikolon steht)"
"
Wie gesagt, weiß nicht obs das schon tut, aber vielleicht ists ein erster Ansatz.
Wenn Du Dir allerdings nicht sicher bist, wie viele ";" vorkommen können,
könnte es etwas komplizierter werden.
Viele Grüße,
Jörg
$newStr = preg_replace ("/"([^"]*?);([^"]*?)"/" , ""\1 \2"" , $csvString);
[/code]
Danke Jörg, leider findet er das nicht :(