Python: Zeile, die nicht mit #beginnen
Ich habe eine Datei, die enthält so etwas wie
# comment
# Kommentar
kein Kommentar# comment
# Kommentar
kein Kommentar
Ich versuche die Datei zu Lesen, Zeile für Zeile und erfassen nur Zeilen, die nicht mit # beginnen. Was ist Los mit meinem code/regex?
import re
def read_file():
pattern = re.compile("^(?<!# ).*")
with open('list') as f:
for line in f:
print pattern.findall(line)
Original-code erfasst alles, was anstelle der erwarteten.
- Der lookbehind-Prüfungen für etwas, das vor der aktuellen position und einer lookahead-Funktion prüft, was nach der aktuellen position. Verwenden Sie einen lookahead, wenn Sie wirklich brauchen einen regex. Aber Sie tun nicht wirklich brauchen, eine regex hier.
- Sie haben zu tun mit
regex
?...Sie können es tun einfach nur mitbuitl-in
Methoden...spart Müheregex
Du musst angemeldet sein, um einen Kommentar abzugeben.
Alternative und dennoch einfachen Ansatz ist, um nur zu überprüfen, wenn die ersten
char
jeder Zeile, die Sie Lesen nicht enthalten#
Charakter:^(?<!# ).*
Arbeit in diesem Fall, nicht wie dies zu tun.line.lstrip().startswith("#")
im Fall der Linie hätte whitespace vor den#
. @Mico: Sie wurden mit einer lookbehind Behauptung statt einer lookahead Behauptung. Lookbehind sieht das neue-Zeile-Zeichen vor dem Anfang der Zeile, nicht die#
Charakter nach dem start von der Linie.^(?!# ).*
regex
Iron Fist zeigt den Weg, wie sollten Sie wohl tun; jedoch, wenn Sie wissen wollen, was war falsch mit Ihrem regex sowieso, sollte es gewesen sein diese:
Erklärung:
^
- match Anfang der Zeile.[^#]
- match etwas, was ist nicht#
.[^...]
ist, wie Sie sagen, nicht zu entsprechen, etwas (einfach zu ersetzen...
mit dem, was die Zeichen, die Sie nicht wollen, zu entsprechen. Zum Beispiel[^ABC123]
übereinstimmen ein Zeichen, das keine A, B, C, 1, 2 oder 3 ist. Lassen Sie sich nicht die^
zeigt, dass die Anfang einer Zeile/string verwechseln Sie hier. Diese beiden^
's sind völlig unabhängig..*
- übereinstimmung mit null oder mehr von etwas anderem.EDIT:
Den Grund
^(?<!# ).*
diskriminiert NICHT zwischen# comment
undnot a comment
ist, dass(?<!#)
prüft den text vor wird die aktuelle position. Der Motor sieht für#
vor dem ersten symbol nach dem start von string, und da gibt es keine#
vor dem start-string, wird jede Zeile ist ein Spiel für.*
subpattern. Um wirklich zu überprüfen, ob das erste Zeichen ist#
, Sie brauchen nur zu verwenden^#.*
regex. Oder, wenn es kann, werden führende Leerzeichen^\s*#
.^(?<!#\s)comment
Arbeit für den OP-text, aber^(?<!#\s).*comment
nicht?Weil:
Es bedeutet, dass es nur Spiel
#
dahinter. Also was ich meine ist:Es ist, weil Sie das falsche token. Also die Antwort ist sehr einfach:
Verwenden
match
Funktion in diesem Fall - da es check-in-Beginn.Also Ausdruck wird
\s*[^#]
- für geistige Gesundheit, die ich verwenden\s
übergeben Leerzeichen.OP-code-
BEARBEITEN-
Ein bisschen Erklärung, warum OP das Muster funktioniert nicht-
Wenn Sie
.
es bedeutet alle außer Zeilenumbruch-Zeichen. Also, wenn Sie schreiben^(?<!# ).*
es bedeutetany
Zeichen (außer Zeilenumbruch - es enthält#
verdammt!) das hat nicht#
vor - schließlich wird jede saite (außer Zeilenumbruch-Variante) beginnt mitany
Charakter.Finden Sie unter LIVE-DEMO
Lösung:
Versuchen
negation
wie^(?<!# )[^#]