2012-04-11 9 views
0

GrundsätzlichBenötigen regulären Ausdruck formulieren helfen Daten zu analysieren

Ich habe Text Ich möchte von einem Textblock auszuspucken. Ich habe den regulären Ausdruck aber größtenteils unten. Es ist entweder zu wenig [überspringt einen Abschnitt] oder zu viel [liest einen Teil des nächsten Abschnitts]. Es muss im Grunde Text lesen, den ich aus einem Kontoauszug extrahiert habe. Ich habe es bereits versucht Ich lese mehr über reguläre Ausdrücke, aber ich habe immer noch keine Ahnung, was ich tun soll.

Heres ein bisschen eine Probe für euch zu verstehen, was ich versuche zu tun.

_4XXXXXXXXXXXXXX9_ 
_SOU THE HOME DEPOT 431  POMPANO BEACH * FL 
AUT 020112 DDA PURCHASE_ 
_2/1_DEBIT POS_3.15_ 

Die Unterstriche sind im Grunde Teile, die ich extrahieren möchte. Grundsätzlich alles außer dem DEBIT POS grundsätzlich.

Und die regex Ich verwende ist:

\A 
(?<SerialNumber>\b[0-9]{13,16}\b) 
(?<Description>.) 'PROBLEM HERE' 
(?<PostingDate> 
(?:1[0-2]|[1-9])/(?:3[01]|[12][0-9]|[1-9])) 
(?<Amount>[,0-9]+\.[0-9]{2}) 
\Z 

Ich kann nicht die Beschreibung von beliebiger Länge von Zeichen zu sein, weil ich weiß nicht, die maximale Länge, dass der Textteil sein wird. Ich weiß auch nicht, ob es 2 Zeilen für die Beschreibung oder nur 1 ist. Das ist hauptsächlich was mich verwirrt.

Antwort

0

Sieht aus wie eine andere einfache Antwort von Regex nicht verwenden. Wenn jede dieser Zeilen eine Zeile ist, wäre es nicht schwer, File.ReadAllLines() und jede Zeile zu analysieren.

public class Order 
{ 
    public string SerialNumber { get; set; } 
    public string Description { get; set; } 
    public DateTime PostingDate { get; set; } 
    public Decimal Amount { get; set; } 

    public void SetSerialNumberFromRaw(string serialNumber) 
    { 
    // Convert to required type, etc. 
    this.SerialNumber = <someConvertedValue>; 
    } 
    public void <OtherNeededValueConverters> 
}  

List<string> lines = File.ReadAlllines("<filename").ToList(); 
List<Order> orders = new List<Order>(); 

Order currentOrder = null; 
foreach (string line in lines) 
{ 
    if (currentOrder = null) 
    { 
    currentOrder = new Order(); 
    orders.Add(currentOrder); 
    currentOrder.SetSerialNumberFromRaw(line); 
    } 
    else 
    { 
    if (line.Contains("DEBIT POS", CultureInfo.CurrentCultureIngoreCase)) 
    { 
     currentOrder.SetPostingDateAndAmount(line); 
     currentOrder = null; 
    } 
    else 
    { 
     currentOrder.SetAppendDescription(line); 
    } 
    } 
} 
+0

Der Grund, warum ich regex verwende, ist, weil ich wissen muss, ob die erste Zeile eine Debit-Transaktion sein wird oder ob es ein Scheck ist und was nicht. Sie variieren nach Zeilenlänge [extrahiert aus PDF und mussten alle Müll entfernen.] Ich kann nicht sagen, dass alle Transaktionen DEBIT POS haben werden. + 4XXXXXXXXXXXXXXX3 + SHELL OIL 57529380602 Coconut Creek * FL + AUT 021.012 VISA DDA PUR + 2/10DEBIT CARD PURCHASE35.05 oder sogar tauschen direkt nach einer Abbuchung und Tagessalden enthalten. –

+0

Dann wäre es nicht schwer, zwei Objekte (oder so viele, wie Sie brauchen) einzurichten, indem Sie in der ersten Zeile Regex ausführen, um den Typ zu erkennen, und dann Code ausführen, der zu diesem Objekt passt, bis Sie ihn gelesen haben das Objekt. –

1

ich denke, Sie alle vier Zeilen zusammen als eine Zeile zuerst anschließen möchten:

var file = @"C:\temp.txt"; 
var lines = System.IO.File.ReadAllLines(file); 
var buffer = new List<String>(); 

for (var i = 0; i < lines.Length; i++) 
{ 
    if (i % 4 == 0) { buffer.Add(""); } 
    buffer[buffer.Count - 1] += lines[i] + " "; 
} 

buffer.ForEach(b => Console.WriteLine(b)); 

Dann können Sie tatsächlich jeden Eintrag in Puffer analysieren, als ob es eine Zeile ist. Dies kann einfach mit Regex oder nur String Substrings erfolgen. Viel einfacher als zu versuchen, dies über mehrere Zeilen hinweg zu tun.

Der obige Code ist nicht der sauberste, aber es funktioniert.

+0

Ich kann nicht alle Linien zusammen zuerst verbinden. Und ich muss auch bestimmen, ob die Beschreibung auch eine Zeile oder zwei sein wird. Hauptgrund, warum ich Regex's in erster Linie benutze. Lesen Sie auch den Kommentar zu @Erik –

+0

Es muss nicht 4 Zeilen jedes Mal sein. Sie können die 4 im obigen Code in eine Variable ändern und dynamisch für jede Startzeile entscheiden, wie viele weitere Elemente vor dem Parsing zu greifen sind. Der Vorschlag ist in erster Linie, dass es einfacher ist, es in zwei Durchgängen zu machen. Eine, um verwandte Linien zusammenzufügen, und die zweite, um Daten aus diesen Linien zu extrahieren. Was sind die identifizierenden Aspekte jeder Art von Datensatz? – yamen

Verwandte Themen