Seite 1 von 1
regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 10:15
von Francesco
hallo, ich möchte Zeilen suchen, deren erstes zeichen nach ein oder mehreren spaces nicht '#' ist.
Wenn ich angebe:
findet sowohl meinstring:
als auch
(dessen zeile aber mit ein oder mehr spaces und '#' beginnt)
Was ist hier falsch?
Nachtrag: hm, brauche ich da eine lookbehind assertion? Die Frage ist aber hauptsächlich, warum er die Zeile mit dem beginnenden Kommentar trotzdem findet.
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 10:55
von cofi
Im Zweiten Fall findet er eben den Teilstring _bis_ zu '#'.
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 10:59
von DaMutz
Ich würde den Leerschlag durch \s ersetzen, es könnte auch sein, dass die Zeile vor dem # kein Leerzeichen hat, darum der *.
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 11:00
von Francesco
cofi hat geschrieben:Im Zweiten Fall findet er eben den Teilstring _bis_ zu '#'.
Danke, da behandelt er das letzte space als [^#] und geht nicht bis zum letzen space. Das habe ich hier falsch aufgefasst.
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 11:03
von Francesco
DaMutz hat geschrieben:
Ich würde den Leerschlag durch \s ersetzen, es könnte auch sein, dass die Zeile vor dem # kein Leerzeichen hat, darum der *.
Ja das ist sicher besser. könnte ja sein, dass die zeile mit tabs beginnt.
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 11:06
von cofi
Aber ehrlich gesagt, finde ich folgendes besser geeignet:
Code: Alles auswählen
code = (line for line in fobj if not line.lstrip().startswith("#"))
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 11:08
von sma
Code: Alles auswählen
import re
s = """
print 1
#print 2
print 3
"""
print(re.findall(r"^ +[^ #].*$", s, re.M))
Das `[^#]` alleine funktioniert nicht, denn dann findet der reguläre Ausdruck eben das Leerzeichen davor (wenn's mindestens 2 sind).
Stefan
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 12:54
von Francesco
Jetzt habe ich noch ein kleines Problem:
wenn ich das so angebe (es soll 0 oder mehr spaces am anfang suchen):
Code: Alles auswählen
import re
s = """
print 1
#print 2
print 3
"""
print(re.findall(r"^ *[^ #].*$", s, re.M))
bekomme ich:
warum ist das \n plötzlich da?
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 13:43
von BlackJack
@Francesco: Wegen dem `re.M`. Damit können Treffer auch über mehrere Zeilen gehen.
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 13:58
von sma
Das \n ist die allererste Leerzeile. Es trifft leider auf [^# ] zu.
Dies sollte gehen wenn man sie auch haben will:
alternativ um sie gleich wegzufiltern:
oder
Das "umdrehen" von Bedingungen in regulären Ausdrücken ist trickreich. Daher ist vielleicht dies die einfachste Lösung:
Code: Alles auswählen
for l in s.splitlines():
if not re.search(r"^ *#", l):
print(l)
Statt `print` könnte man ein `yield` nehmen und das ganze in eine Funktion packen und man hat einen schicken Iterator.
Stefan
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 14:43
von Francesco
@Blackjack: Ja, aber warum das erste Zeichen '\n' als das erste Zeichen nach Zeilenanfang ( '^') mitgenommen wird, verstehe ich trotzdem nicht. gilt das multiline sowohl als stringbeginn als auch für Zeilenbeginn (so schätze ich wird es wohl sein)
@Stefan. Das mit der umgekehrten Abfrage finde ich auch eine sehr gute Idee.
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 22:52
von sma
Francesco hat geschrieben:@Blackjack: Ja, aber warum das erste Zeichen '\n' als das erste Zeichen nach Zeilenanfang ( '^') mitgenommen wird, verstehe ich trotzdem nicht.
Ich hatte die Erklärung eigentlich gegeben. Schau dir den Anfang des Strings an: \nprint1\n#print2...
Das `findall` beginnt bei Index 0. Dies ist ein Zeilenanfang, also passt ^. Nun sollen 0 oder mehr Leerzeichen folgen. Das passt, denn es folgen 0 Leerzeichen. Nun soll ein zeichen folgen, das kein Leerzeichen oder # ist. Das \n (denn ich bin immer noch an Index 0) ist so ein Zeichen, also wird das genommen. Nun werden mit .* (da re.S == DOTALL nicht gesetzt ist) alles bis zum nächsten Zeilenende bzw. Ende des Strings gelesen, in diesem Fall print1. Das folgende \n wird ebenfalls verschluckt und `findall` würde jetzt bei #print weitersuchen.
Stefan
Re: regex: bestimmte zeilen suchen
Verfasst: Samstag 3. Juli 2010, 23:09
von Francesco
sma hat geschrieben:
Ich hatte die Erklärung eigentlich gegeben. Schau dir den Anfang des Strings an: \nprint1\n#print2...
Das `findall` beginnt bei Index 0. Dies ist ein Zeilenanfang, also passt ^. Nun sollen 0 oder mehr Leerzeichen folgen. Das passt, denn es folgen 0 Leerzeichen. Nun soll ein zeichen folgen, das kein Leerzeichen oder # ist. Das \n (denn ich bin immer noch an Index 0) ist so ein Zeichen, also wird das genommen. Nun werden mit .* (da re.S == DOTALL nicht gesetzt ist) alles bis zum nächsten Zeilenende bzw. Ende des Strings gelesen, in diesem Fall print1. Das folgende \n wird ebenfalls verschluckt und `findall` würde jetzt bei #print weitersuchen.
Stefan
Ja danke, jetzt ist es mir klar.