2016-05-16 9 views
0

Ich baue einen Parser in Python und in einem Schritt des Parsers muss er sich die nächsten paar Zeilen ansehen, um festzustellen, ob ein Wert vorhanden ist. Um dies zu tun, ich tue das folgende:Indexieren einer Liste in Python mit Nummer, wenn der Listenindex nicht außerhalb des Bereichs liegt

if "Account Summary" in line: 
    end_bal_regex = r"Ending balance on (.*?)\s+(-?\$[\d,]+\.\d\d)" 
    end_date, end_bal = [re.search(end_bal_regex, text[i+j], re.IGNORECASE).groups() for j in range(1,16) if re.search(r"Ending balance", text[i+j], re.IGNORECASE)][0] 

Dies funktioniert gut 99% der Zeit, aber manchmal gibt es nicht mehr als 15 Zeilen Text nach der Zeile, die „Kontoübersicht“ hat. Gibt es einen Weg, im Listenverständnis etwas wie text[i+j] or text[i:] (offensichtlich Pseudocode) zu sagen? Meine Vermutung ist, dass ich dies zu einem normalen for Schleife und so etwas tun umwandeln müssen werden:

if "Account Summary" in line: 
    end_date, end_bal = None, None 
    for j in range(1,16): 
     if j > len(text[i:]): 
      break 
     if re.search(r"Ending balance", text[i+j], re.IGNORECASE): 
      end_date, end_bal = re.search(end_bal_regex, text[i+j], re.IGNORECASE).groups() 

ich wirklich nicht alle meine verschiedenen Zeilen Code neu schreiben möchten, haben (es gibt mehrere genau wie diese) zu diesem Format, aber ich bin mir nicht bewusst, dass irgendetwas erreicht, was ich brauche. Jeder Einblick oder Rat wird geschätzt.

lines = ["Account Summary", "Beginning Balance", "Random Text 1", "Random Text 2", "Random Text 3", "Random Text 4", "Ending Balance"] 
+0

ich nicht ganz verstehen, was du tust, aber ich:

Für ein reproduzierbares Beispiel können Sie die folgenden Befehle verwenden d rate benutze 'line [line.index (" Account Summary "):]', um alle Werte nach "Account Summary" zurückzugeben, egal wie viele/kleine es sind (oder nutze zumindest, um wie viele Werte zu bekommen) Es gibt), anstatt 16 zu verwenden. – Peter

+0

@Peter Ich denke, dass Ihr erster Vorschlag ziemlich gut funktionieren könnte, wenn es nicht gibt ein "eingebauter" Ansatz für dieses Problem. Obwohl man leicht argumentieren könnte, dass "try/except" ein integrierter Ansatz für dieses Problem ist. Der zweite Ansatz wäre zu viel, da es mehr als 500 bis 1000 Zeilen Text geben könnte und ich möchte nicht alle davon überprüfen. – brittenb

Antwort

1

Ändern der Grenze 16 zu min(16, len(text[i:]))

... for j in range(1, min(16, len(text[i:]))) re.search(r"Ending balance", text[i+j], re.IGNORECASE)][0] 
+0

Seufz ... es ist immer die einfachste Lösung, die ich nie realisiert habe. – brittenb

Verwandte Themen