2017-05-25 7 views
1

Ich habe eine Logdatei für dieses Skript erstellt, die ich geschrieben habe, und ich möchte nach Fehlern suchen.Regex Suche Lookaround

Das Logfile sieht wie folgt aus:

24/05/2017 07:39:55 PM | DEBUG | Reading config file "FRGD-1_1.cfg". | main.py:81 - set_configparser() 
... 
... 
24/05/2017 07:39:55 PM | DEBUG | Reading config file "FRGD-1_10.cfg". | main.py:81 - set_configparser()  
... 
... 
24/05/2017 08:39:55 PM | DEBUG | Reading config file "RFGD-1_5.cfg". | main.py:81 - set_configparser()  
...  
25/05/2017 09:53:47 PM | ERROR | KeyError. There is an issue with the config file for this download. Please check the config file for errors. | script.py:137 - main()  
... 
... 
24/05/2017 10:39:55 PM | DEBUG | Reading config file "DPGD-4_15.cfg". | main.py:81 - set_configparser() 
... 
... 
24/05/2017 11:39:55 PM | DEBUG | Reading config file "ZXTD-3_1.cfg". | main.py:81 - set_configparser() 
... 
25/05/2017 03:53:47 AM | ERROR | KeyError. There is an issue with the config file for this download. Please check the config file for errors. | script.py:137 - main()  
... 
... 
24/05/2017 07:39:55 PM | DEBUG | Reading config file "FRGD-1_1.cfg". | main.py:81 - set_configparser() 
... 
... 
24/05/2017 07:39:55 PM | DEBUG | Reading config file "FRGD-1_10.cfg". | main.py:81 - set_configparser() 

ich alle Namen der Konfigurationsdateien aufnehmen möchten, die einen Fehler ausgelöst haben.

die Linien zu identifizieren, suche ich nach Linien, die haben:

DD/MM/YYYY HH:MM:SS PM | DEBUG | Reading config file "<file_name>.cfg". 

direkt vor:

DD/MM/YYYY HH:MM:SS PM | ERROR | 

Im Beispiel oben, sie sind "RFGE-1_5.cfg" und „ZXTD -3_1.cfg ".

ich Python bin mit diesem regulären Ausdruck laufen, als solche ich die ganze Datei zu einer einzigen Zeile verkettet haben und verwendet die folgende regex

'(?<=Reading config file "(.{13})").+?\| ERROR \|'. 

Leider funktioniert es nicht.

Jede Hilfe wäre großartig.

Antwort

1

Intuitiv würde man sagen, dass die letzten config file vor übereinstimmen. Mit dem neueren regex Modul, ist eine Variable möglich Lookbehind etwa so:

import regex as re 
rx = re.compile(r''' 
       (?<=config\ file\ "([^"]+)"(?s:.*?)) 
       \|\ ERROR\ \| 
       ''', re.VERBOSE) 

print(rx.findall(string)) 
# ['RFGD-1_5.cfg', 'ZXTD-3_1.cfg'] 

a demo on regexstorm.com anzeigen (klicken Sie auf Tabelle).


Ein bisschen eine Erklärung hier:

(?<=    # a pos. lookbehind    
    config file # config file literally 
    \"([^\"]+)\" # capture anything between "..." 
    (?s:.*?)  # turns on single line mode (dot matches all including newline), 
       # lazily, expanded as needed 
)    # closing lookbehind 
\| ERROR \|  # | ERROR | literally 

Beachten Sie, dass die Whitespaces als auch in verbose mode und dass die doppelten Anführungszeichen es werden nicht werden müssen entkommen müssen entkommen (macht nur ziemlich auf StackOverflow).
Dies funktioniert nur mit dem neueren Modul regex, da der Lookbehind von beliebiger Länge sein kann.

+0

Hallo Jan. Danke für Ihre Zeit. Das funktioniert genau wie Magie. Könnte ich Sie fragen, was Sie in diesem Abschnitt tun: (? S:. *?) –

+0

@jerry_doe: Yup, siehe die modifizierte Antwort. – Jan

+0

Vielen Dank Jan. Das war brilliant. Ich bin sehr dankbar. –