Seite 1 von 1
Problem mit (...)?
Verfasst: Freitag 1. Januar 2010, 20:18
von saltorückwärts
hallo zusammen,
ich möchte das muster
in jeder zeile einer datei filtern...
folgendes funktioniert aber nicht:
Code: Alles auswählen
file = open("bla")
for line in file:
print line
matches = re.findall(re.compile(pattern, re.I), line)
for match in matches:
print match
wenn ich das ausführe, werden ausdrücke von z.B. der form 2GB nicht gefiltert... warum nicht ? ich hab denselben regexp mit egrep genommen, da funktioniert's... testweise habe ich mal den regulären ausdruck
statt dem obigen genommen, damit wird 2GB gefiltert... vermutung also, dass es irgendwie an den (...)? unterausdrücken liegt...
kann mir da jemand genaueres sagen ?
ich arbeite unter windows/cygwin
gruß
Verfasst: Freitag 1. Januar 2010, 20:33
von Defnull
1) Ein re.compile innerhalb eines re.findall macht keinen Sinn.
2) re.findall gibt keine match-objekte zurück. Benutz finditer() dafür.
3) Ausdrücke sind in der Regel case sensitiv.
4) "[^0-9]" führt dazu, das '2GB' am Zeilenanfang nie gefunden wird.
Code: Alles auswählen
import re
pattern = re.compile(r'(?<![0-9])2\s*g(iga)?\s*b(yte)?', re.IGNORECASE)
with open('bla') as myfile:
for line in myfile:
for match in pattern.finditer(line):
print match
Verfasst: Freitag 1. Januar 2010, 20:34
von Darii
Vielleicht solltest du dir mal in der Doku angucken, wie die Regexp-Syntax von Python aussieht. (...) gibt Gruppen an. Auch sonst sieht ein Ausdruck seltsam aus. Was willst du überhaupt filtern, also was soll aus 2GB werden?
Verfasst: Freitag 1. Januar 2010, 20:34
von HWK
Du verwendest ignorecase? Vor der 2 steht eine Nicht-Zahl?
Übrigens: [^0-9] == \D
MfG
HWK
Edit: Zu spät
Verfasst: Freitag 1. Januar 2010, 21:35
von saltorückwärts
danke schonmal für die antworten... das mit dem compile stimmt natürlich
soweit ich gelesen hab gibt findall eine liste von strings zurück auf die der reguläre ausdruck passt, die kann ich doch dann einfach 'matches' nennen und drüber iterieren und mir die strings ausgeben lassen...
es sollen ausdrücke der form "2 GB", "2 GByte" und alles mögliche sonst gefiltert werden, was in der hinsicht denkbar ist
die [^0-9] muss vor die 2, weil ich "32 GB" nicht als "2 GB" filtern will, die angabe steht nie am zeilenanfang von daher ist es egal...
was also nun nicht funktioniert, ist:
Code: Alles auswählen
file = open("bla")
pattern = re.compile(r'(?<![0-9])2\s*g(yte)?\s*b(yte)?', re.IGNORECASE)
for line in file:
matches = re.findall(pattern, line)
for match in matches:
print match
bei einer zeile in der "2GB" vorkommt, krieg ich als Ausgabe ('', ''), wobei '' der leere string bedeutet...
was hingegen funktioniert ist
Code: Alles auswählen
file = open("bla")
pattern = re.compile(r'(?<![0-9])2\s*g\s*b', re.IGNORECASE)
for line in file:
matches = re.findall(pattern, line)
for match in matches:
print match
bei einer zeile in der "2GB" vorkommt, krieg ich als Ausgabe "2GB" so wie es sein soll... da ich im zweiten fall nur die (...)? ausdrücke weggelassen hab, muss es scheinbar daran liegen... meine frage ist warum
Verfasst: Freitag 1. Januar 2010, 21:41
von Darii
saltorückwärts hat geschrieben:bei einer zeile in der "2GB" vorkommt, krieg ich als Ausgabe "2GB" so wie es sein soll... da ich im zweiten fall nur die (...)? ausdrücke weggelassen hab, muss es scheinbar daran liegen... meine frage ist warum
Wie ich schon schrieb matched (...) auf Gruppen. findall gibt die gefundenen Gruppen(sofern vorhanden) zurück(siehe
Doku).
Minimalbeispiele helfen da beim Verstehen immer am besten:
Code: Alles auswählen
In [3]: re.findall("G(iga)?","Giga")
Out[3]: ['iga']
In [4]: re.findall("G(iga)?","G")
Out[4]: ['']
In [5]: re.findall("G(iga)","G")
Out[5]: []
Du willst also vermutlich eher sowas wie G[iga]? verwenden
Verfasst: Freitag 1. Januar 2010, 21:52
von saltorückwärts
uff... ja, kapiert, vielen dank

hab nur die ersten zwei sätze der funktionsbeschreibung gelesen, das mit den gruppen wird erst im dritten erwähnt
naja, damit hat sich die sache jedenfalls erledigt

Verfasst: Samstag 2. Januar 2010, 12:07
von sma
Benutze `(?:...)` statt `(...)`.
Stefan
Verfasst: Montag 4. Januar 2010, 12:21
von birkenfeld
Darii hat geschrieben:
Du willst also vermutlich eher sowas wie G[iga]? verwenden
Was dann auf "G", "Gi", "Gg" und "Ga" matcht? Wohl kaum.