2016-08-01 16 views
-1

Ich habe einige Config-Datei, aus denen ich nur einige Werte extrahieren muss. Zum Beispiel, ich habe dies:Regex nur Teil einer bestimmten Linie

PART 
{ 
    title = Some Title 
    description = Some description here. // this 2 params are needed 
    tags = qwe rty // don't need this param 
    ... 
} 

Ich muss Wert bestimmter param extrahieren, zum Beispiel description ‚s-Wert. Wie mache ich das in Python3 mit Regex?

Antwort

1

ist die Regex, unter der Annahme, dass die Datei Text in txt ist:

import re 

m = re.search(r'^\s*description\s*=\s*(.*?)(?=(//)|$)', txt, re.M) 
print(m.group(1)) 

Lassen Sie mich erklären. ^ Übereinstimmungen am Zeilenanfang. Dann \s* bedeutet Null oder mehr Leerzeichen (oder Tabs) description ist Ihr Anker für die Suche nach dem Wert Teil. Danach erwarten wir = Zeichen mit optionalen Leerzeichen davor oder danach mit der Bezeichnung \s*=\s*. Dann erfassen wir alles nach dem = und optionalen Leerzeichen, indem wir (.*?) bezeichnen. Dieser Ausdruck wird durch Klammern erfasst. Innerhalb der Klammer sagen wir, dass Sie alles (den Punkt) so oft wie möglich (das Sternchen) auf nicht-gierige Weise (das Fragezeichen) finden, dh stoppen, sobald der folgende Ausdruck übereinstimmt.

Der folgende Ausdruck ist ein Lookahead-Ausdruck, der mit (?= beginnt, der der Sache unmittelbar nach dem (?= entspricht. Und das Ding ist eigentlich zwei Optionen, getrennt durch die vertikale Leiste |.

Die erste Option, links von der Leiste sagt // (in Klammern, um es Atomeinheit für die vertikale Bar Wahl Operation machen), das heißt, der Beginn des Kommentars, die, ich nehme an, Sie nicht möchte erfassen. Die zweite Option ist $, was das Ende der Zeile bedeutet, das erreicht wird, wenn in der Zeile kein Kommentar // steht. Also suchen wir nach allem, was wir können nach dem ersten = Zeichen, bis entweder wir treffen ein // Muster, oder wir treffen das Ende der Linie. Dies ist die Essenz des (?=(//)|$) Teils.

Wir müssen auch die re.M Flagge, die Regex-Engine sagen, dass wir wollen ^ und $ den Anfang und das Ende von Zeilen entsprechen, respectively. Ohne das Flag passen sie den Anfang und das Ende der gesamten Zeichenfolge an, was in diesem Fall nicht das ist, was wir wollen.

-1

Dies ist eine ziemlich einfache Regex, Sie brauchen nur einen positiven Lookbehind und optional etwas, um die Kommentare zu entfernen. (Tut dies, indem ?(//)? auf den regex Anhang)

r"(?<=description =).*" 

Regex101 demo

+0

Kommentare wurde von mir nur für Claryfying hinzugefügt: P – Kerbiter

+0

Dies wird auch die Doc-Zeile übereinstimmen. – Kasramvd

+0

Was ist die "Doc-Linie"? – RamenChef

0

Der bessere Ansatz wäre ein etabliertes Konfigurationsdateisystem zu verwenden. Python verfügt über eine integrierte Unterstützung für INI-ähnliche Dateien im Modul configparser.

Wenn Sie jedoch nur dringend Notwendigkeit, die Textzeichenfolge in der Datei nach dem description zu bekommen, können Sie dies tun:

def get_value_for_key(key, file): 
    with open(file) as f: 
     lines = f.readlines() 
    for line in lines: 
     line = line.lstrip() 
     if line.startswith(key + " ="): 
      return line.split("=", 1)[1].lstrip() 

Sie können es mit einem Aufruf wie verwenden: get_value_for_key("description", "myfile.txt"). Die Methode gibt None zurück, wenn nichts gefunden wird. Es wird angenommen, dass Ihre Datei dort formatiert wird, wo ein Leerzeichen und das Gleichheitszeichen nach dem Schlüsselnamen vorhanden ist, z. key = value.

Dadurch werden reguläre Ausdrücke vermieden und alle Leerzeichen auf der rechten Seite des Werts beibehalten. (Wenn Ihnen das nicht wichtig ist, können Sie strip anstelle von lstrip verwenden.)

Warum reguläre Ausdrücke vermeiden? Sie sind teuer und wirklich nicht ideal für dieses Szenario. Verwenden Sie einfache Zeichenfolgenabgleiche. Dies vermeidet den Import eines Moduls und vereinfacht Ihren Code. Aber ich würde sagen, dass ich in ein unterstütztes Konfigurationsdateiformat konvertieren soll. Hier

Verwandte Themen