Ich habe diesen rohen Text:
%Vor%Ich muss es in ein Objekt mit den offensichtlichen Feldern Position, Car, Driver usw. parsen. Das Problem ist, dass ich keine Ahnung habe, welche Art von Strategie zu verwenden ist. Wenn ich es auf Leerzeichen aufteilen würde, würde ich eine Liste wie folgt erhalten:
%Vor%Können Sie das Problem sehen? Ich kann diese Liste nicht einfach interpretieren, weil die Leute nur einen Namen haben, oder drei Wörter in einem Namen oder viele verschiedene Wörter in einem Auto. Es macht es unmöglich, die Liste nur mithilfe von Indizes zu referenzieren.
Was ist mit den Offsets, die durch die Spaltennamen definiert sind? Ich kann jedoch nicht sehen, wie das verwendet werden könnte.
Bearbeiten : Der aktuelle Algorithmus, den ich verwende, funktioniert folgendermaßen:
Es gibt mehrere Probleme:
Wenn die Namen die gleichen Längen wie folgt enthalten:
%Vor% Dann wird es das als zwei separate Elemente interpretieren: ([ "Jason" "Adams", "Bobby", "Sacka", "Jerry", "Louis"]
).
Wenn sie alle so unterschieden:
%Vor% Dann würde es korrekt auf dem letzten 'd' in Seinfeld aufgeteilt werden (und somit würden wir eine Sammlung von drei Namen bekommen ( ["Dominic Bou", "Bob Adams", "Jerry Seinfeld"]
).
Es ist auch ziemlich brüchig. Ich suche eine bessere Lösung.
Sie können das fixed_width
Juwel verwenden.
Ihre angegebene Datei kann mit dem folgenden Code analysiert werden:
%Vor% Die Methode trap
identifiziert die Linien in jedem Abschnitt. Ich habe Regex verwendet:
head
regex sucht nach Zeilen, die keine Ziffer enthalten. body
Regex sucht nach Zeilen, die mit einer Ziffer oder "DNF" Jeder Abschnitt muss die Zeile unmittelbar nach der letzten enthalten. Die column
-Definitionen identifizieren einfach die Anzahl der zu greifenden Spalten. Die Bibliothek streift Leerzeichen für Sie. Wenn Sie eine Datei mit fester Breite erzeugen möchten, können Sie Ausrichtungsparameter hinzufügen. Sie werden jedoch nicht benötigt.
Das Ergebnis ist ein Hash, der folgendermaßen beginnt:
%Vor%Das ist kein guter Fall für Regex, Sie wollen das Format wirklich entdecken und dann die Zeilen entpacken:
%Vor%Ich denke, es ist einfach genug, einfach die festgelegte Breite in jeder Zeile zu verwenden.
%Vor%Ausgabe = & gt;
%Vor%Je nachdem, wie konsistent die Formatierung ist, können Sie wahrscheinlich Regex dafür verwenden.
Hier ist ein Beispiel-Regex, das für die aktuellen Daten funktioniert - muss möglicherweise abhängig von genauen Regeln optimiert werden, aber es gibt die Idee:
%Vor%Wenn Sie sicherstellen können, dass der Leerraum Leerzeichen und keine Tabulatoren ist und dass überlanger Text immer abgeschnitten wird, damit er in die Spaltenstruktur passt, dann würde ich die Slice-Grenzen fest codieren:
%Vor%Abhängig von der Datenquelle kann dies spröde sein (wenn beispielsweise jeder Lauf unterschiedliche Spaltenbreiten hat).
Wenn die Kopfzeile immer gleich ist, können Sie die Schichtgrenzen extrahieren, indem Sie nach den bekannten Wörtern der Kopfzeile suchen.
Okay, ich hab's verstanden:
Bearbeiten : Ich habe vergessen zu erwähnen, dass Sie den eingegebenen Text in der Variable input_string
Ausgaben:
%Vor%Und für den Fall, dass Arrays es nicht schneiden
%Vor%Ich lasse es in nette Funktionen für Sie umgestalten.
Wenn es keine klare Regel dafür gibt, wie die Spalten getrennt sind, können Sie das nicht wirklich tun.
Der Ansatz, den Sie haben, ist gut, vorausgesetzt Sie wissen , dass jeder Spaltenwert korrekt in den Spaltentitel eingerückt ist.
Ein anderer Ansatz könnte darin bestehen, Wörter zu gruppieren, die genau um ein Leerzeichen getrennt sind (aus dem Text, den Sie angegeben haben, kann ich sehen, dass diese Regel ebenfalls gilt).
Vorausgesetzt, dass der Text immer denselben Abstand hat, können Sie die Zeichenfolge basierend auf der Position aufteilen und dann zusätzliche Leerzeichen um jedes Teil entfernen. Zum Beispiel in Python:
%Vor%und so weiter. Alternativ könnten Sie einen regulären Ausdruck definieren, um jedes Teil zu erfassen:
%Vor%und so weiter. (Die genaue Syntax hängt von Ihrer Regexp-Grammatik ab.) Beachten Sie, dass die Auto-Regexp die hinzugefügten Leerzeichen verarbeiten muss.
Ich werde das nicht programmieren, aber eine Methode, die definitiv für den obigen Datensatz funktioniert, besteht darin, sie nach Leerraum zu analysieren und dann Elemente auf diese Weise zuzuordnen:
%Vor%Der Fahrzeugteil kann durch eine Art For- oder While-Schleife erfolgen.
Tags und Links ruby language-agnostic parsing text screen-scraping