Ich habe den Auftrag, einen Parser zu erstellen, der eine bestimmte Webseite analysiert, so dass unsere Mitarbeiter einen Großteil ihrer Benutzerdaten in ihre Website mit unserer Firma importieren können.
Ich habe das HtmlAgilityPack verwendet , um die Seite zu analysieren. Ich habe die table row
und table data
so korreliert, dass sie in Eigenschaften in meiner Map
Klasse eingefügt werden .
Aber eine Kolumne verursacht mir viel Kummer. Die Adressspalte ist mir aus verschiedenen Gründen ein Dorn im Auge.
Beispieldaten:
6313 SW 203rd Ave <br> Portland, OR 97224
16600 Lomita Way <br> El Dorado Hills, CA 95762
PO Box #42 <br> Hampton Bays, NY 11946
Jede dieser Adressen wird wie folgt verpackt (Offensichtlich können die Adressen basierend auf dem Kunden variieren, für den wir Benutzer importieren):
<tr>
<td> 6313 SW 203rd Ave <br> Portland, OR 97224 </td>
</tr>
Ich versuche, einen regulären Ausdruck zu implementieren, um diesen im richtigen Bereich zu teilen, damit er den entsprechenden Eigenschaften zugewiesen werden kann:
public string Unit { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
Allerdings bieten die Adressen nicht viel an, um zu verankern von:
Frage eins: Wenn ich an der <br>
dann bin ich nur die Linien getrennt. Teilt nicht vollständig in richtige Segmente auf.
Problem 2: Gleiches Problem mit dem einzelnen Komma.
Problem drei: Wenn ich an numerische Werte ankere, ist die Zip-Datei möglicherweise für Kanada ungültig und wird möglicherweise aufgrund des Straßennamens nicht richtig geteilt.
Was ist der beste Weg, um Elemente für eine Adresse zu trennen? Mit Regex?
Okay, das Address
war ziemlich schmerzhaft zu analysieren. Jedoch habe ich es geschafft, die Daten basierend auf meinen speziellen Anforderungen zu parsen.
Address
immer ein <br>
zwischen der Street & City. Also habe ich Folgendes getan:
var splitBasedOnHTML = Regex.Split(column[2], @"\br<br>");
Die column[]
enthält meine Adresse in index two
. Nach diesem Anruf wird meine Einheit und meine Straße automatisch im Index Zero
positioniert. Die Stadt, der Staat und die Postleitzahl befinden sich im Index One
.
Also machte ich einen weiteren Split, um die City, State, und Zip so zu brechen:
var splitBasedOnSpace = splitBasedOnHtml[1].Split(' ');
Danach habe ich nun folgendes:
6313 SW 203rd Ave // splitBasedOnHtml[0]
Portland, // splitBasedonSpace[0]
OR // splitBasedOnSpace[1]
97224 // splitBasedOnSpace[2]
Also habe ich einfach meine Eigenschaften diesen einzelnen Array-Indizes zugeordnet.
Diese Lösung macht die Annahme, dass die Einheit ein Teil der Straße ist , was ein gutes Opfer wird, da die Daten in eine andere Website importiert werden und später von bestimmten Personen geändert werden können.
Das ist, wie ich die parse Probleme gelöst habe, ist diese Lösung für andere in diesem Boot vielleicht nicht lebensfähig, aber hoffentlich ist das eine gute Alternative oder zeigt in eine gute Richtung. Wie die Methode aussieht:
public static Map AddressMapper(IList<string> column)
{
var map = new Map();
var splitBasedOnHTML = Regex.Split(column[2], @"\b<br>");
var splitBasedOnSpace = splitBasedOnHTML[1].Split(' ');
map.Street = splitBasedOnHTML[0];
map.City = splitBasedOnSpace[0].Replace(@",", " ");
map.State = splitBasedOnSpace[1];
map.Zip = spliteBasedOnSpace[2];
return map;
}
Parsen von Adressen ist schwer; sehr hart. Es gibt kein wirklich einheitliches Format für Adressen, insbesondere über Landesgrenzen hinweg. Es ist sehr unwahrscheinlich, dass Sie dies mit einem einzigen RegEx tun können.
In diesem anderen Beitrag finden Sie einige Beispiele und eine ausführlichere Erläuterung. Wie man Freiform Straße / Postadresse aus Text und in Komponenten analysiert