Wie kann ich analysieren zitiert CSV in Perl mit regex?
Ich habe einige Probleme mit dem Parsen von CSV-Daten, die mit Anführungszeichen. Mein Hauptproblem ist mit Anführungszeichen innerhalb eines Feldes. Im folgenden Beispiel werden die Zeilen 1 - 4 die Arbeit korrekt, aber 5,6 und 7 nicht.
COLLOQ_TYPE,COLLOQ_NAME,COLLOQ_CODE,XDATA
S,"BELT,FAN",003541547,
S,"BELT V,FAN",000324244,
S,SHROUD SPRING SCREW,000868265,
S,"D" REL VALVE ASSY,000771881,
S,"YBELT,"V"",000323030,
S,"YBELT,'V'",000322933,
Ich möchte vermeiden, Text::CSV, da es nicht auf dem Zielserver installiert. Zu realisieren, dass die CSV ' s sind komplizierter als Sie Aussehen, ich bin mit einem Rezept aus dem Perl-Kochbuch.
sub parse_csv {
my $text = shift; #record containg CSVs
my @columns = ();
push(@columns ,$+) while $text =~ m{
# The first part groups the phrase inside quotes
"([^\"\\]*(?:\\.[^\"\\]*)*)",?
| ([^,]+),?
| ,
}gx;
push(@columns ,undef) if substr($text, -1,1) eq ',';
return @columns ; # list of vars that was comma separated.
}
Hat jemand einen Vorschlag zur Verbesserung der regex zum behandeln der oben genannten Fällen?
Sind nicht Linien 5, 6 und 7 ungültige CSV?
InformationsquelleAutor Mark Nold | 2009-03-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bitte, Versuchen Sie es Mit CPAN
Gibt es keinen Grund, Sie konnte nicht laden Sie eine Kopie von Text::CSV, oder andere nicht-XS-basierte implementation einer CSV-parser und installieren Sie es in Ihrem lokalen Verzeichnis oder in einem lib/- Unterverzeichnis Ihres Projekts, so dass die installierte zusammen mit Ihrer rollout-Projekte.
Wenn Sie nicht speichern Sie text-Dateien in Ihrem Projekt, dann Frage ich mich, wie es ist, Sie Programmieren Ihr Projekt.
http://novosial.org/perl/life-with-cpan/non-root/
Sollte eine gute Anleitung, wie man diese in einen funktionierenden Zustand vor Ort.
Nicht mit CPAN ist wirklich ein Rezept für eine Katastrophe.
Bitte beachten Sie dies, bevor Sie versuchen zu schreiben Sie Ihre eigenen CSV-Umsetzung.
Text::CSV ist über hundert Zeilen code, einschließlich der Behebung von bugs und Sonderfälle, und neu schreiben, dieses von Grund auf neu wird nur machen Sie lernen, wie schrecklich CSV können Sie die harte Weise.
Hinweis: ich lernte das auf die harte Art und Weise. Hat mich einen ganzen Tag, um eine funktionierende CSV-parser in PHP, bevor ich entdeckte einen eingebauten wurden in einer späteren version. Es ist wirklich etwas schreckliches.
Möglicherweise möchten Sie auch zu schauen, Text::xSV , die ist auch Reine Perl
Ich werde zu prüfen haben, die als Text:CSV_PP funktioniert nicht mit dem fünften Fall sogar mit allow_loose_quotes und escape_char gesetzt. Nochmals vielen Dank.
Ich habe zu tun gehabt mit junior-Programmierer anspruchsvolle jedes CPAN-Modul unter der Sonne installiert werden, wenn eine einfache regexp gereicht hätte. Die Perl-community advocates "es gibt mehr als einen Weg, es zu tun", so sprühen Sie Malerei GROß und FETT, als wenn es NUR EIN ANSATZ nicht helfen, diejenigen, die wirklich wollen, zu entdecken, eine alternative Methode.
das ist nicht halb so schlimm wie die weitere Häufig auftretende situation, die ist ein Schmerz in den Arsch zu leugnen, die Verwendung eines Moduls für die keine Remote vernünftigen Grund, weil Sie weder verstehen, die unzähligen Möglichkeiten, dass "eine einfache regex" ausfällt, um den job gut, noch den Ehrgeiz haben zu lernen.
InformationsquelleAutor Kent Fredric
Können Sie parse CSV mit Text::ParseWords, die Schiffe mit Perl.
welche analysiert Ihre CSV-Datei korrekt....
Das einzige Problem, ich hatte schon mit Text::ParseWords ist, wenn verschachtelte Zitate in Daten nicht korrekt maskiert. Dies ist jedoch schlecht gebaut CSV-Daten und würde Probleme verursachen mit die meisten CSV-Parser 😉
So können Sie feststellen, dass
kam heraus, als (ie. Zitate fiel etwa "V")
aber wenn Ihr entkam wie so
zitiert dann beibehalten werden
und @mirod danke für den Zeiger. Ich Teste das jetzt, danke.
Leider, es sei denn, Sie haben einen Zustand-Pflege-parser, kann man nicht analysieren alle CSV auf einer line-by-line-basis. Einige CSV ' s haben wörtlich Zeilenumbrüche innerhalb von Zeichenfolgen, und dieser nach der Tat macht das Parsen der CSV ein Alptraum. ie: Wenn Sie lösen das line-feed-Problem selbst, das dann so aus: gist.github.com/1329430 , aber wenn Sie den code wie vorgeschlagen, auf die wörtlichen Daten; Sie erhalten diese Monstrosität gist.github.com/1329436 . Feinheiten wie diese sind, warum benötigen Sie einen echten parser 😉
Dieser schlägt fehl, wenn der string enthält 2 Zitate in eine Zeile, z.B. "sagte er "Hallo""
Das ist ungültiges CSV, also bin ich nicht überrascht, dass es fehlschlägt.
InformationsquelleAutor draegtun
Dies funktioniert wie Charme
Linie wird angenommen, dass durch Kommata getrennt werden mit eingebunden ,
my @columns = Text::ParseWords::parse_line(',', 0, $line);
InformationsquelleAutor Sidharth N. Kashyap
getestet, funktioniert:-
gewarnt werden, die CSV-Dateien enthalten kann, die Zellen mit eingebetteten Zeilenumbrüche innerhalb der Anführungszeichen, so müssen Sie dies tun, wenn das Lesen der Daten in-line-at-a-time:
InformationsquelleAutor Chris
Finden Sie passende Paare mit regexs ist nicht trivial und in der Regel unlösbare Aufgabe. Es gibt viele Beispiele in der Jeffrey Friedl ' s Mastering regular expressions Buch. Ich habe es nicht zur hand jetzt, aber ich erinnere mich, dass er CSV-Format für einige Beispiele, zu.
Dank Eugene, komischerweise bin ich mir ziemlich sicher, dass das Perl-Kochbuch, das Beispiel ist entnommen aus MRE 🙂 ich werde überprüfen, wenn.
/((?:[^\n,"]|"(?:[^"]|"")+")+),/g sein sollte, näher zu dem, was der OP will, ist aber durch meine eigene Zulassung noch unvollkommen.
Ja, ich glaube Zitate, wie Sie ist, in einem quotierten Bereich ist ungültig CSV, da gibt es einige die Flucht mechansim erforderlich, ansonsten arbeitet es heraus, indem Sie Spekulationen ist einfach unmöglich.
InformationsquelleAutor Eugene Morozov
Können Sie (versuchen zu) nutzen CPAN.Uhr einfach Ihrem Programm installieren/aktualisieren-Text::CSV. Wie gesagt, Sie kann sogar "installieren", um es in ein Haus oder ein lokales Verzeichnis, und fügen Sie das Verzeichnis in @INC (oder, wenn Sie lieber nicht verwenden
BEGIN
- Blöcke, können Sieuse lib 'dir';
- es ist wohl besser).InformationsquelleAutor Chris Lutz
Getestet:
Ich getesteten code. Sie Tat es nicht. Einige Leute finden regelmäßige Ausdrücke schwierig. Das ist in Ordnung. Ich ganz gerne, und genießen, reguläre Ausdrücke (wahrscheinlich der Grund, warum ich benutze Emacs).
gist.github.com/1329456 # dein code auf einen Beispieldatensatz mit einem line feed in der Mitte des Feldes. Genießen =).
InformationsquelleAutor PP.