Problem mit (...)?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
saltorückwärts
User
Beiträge: 3
Registriert: Freitag 1. Januar 2010, 20:02

hallo zusammen,

ich möchte das muster

Code: Alles auswählen

pattern = "[^0-9]2 *g(iga)? *b(yte)?"
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

Code: Alles auswählen

pattern = "[^0-9]2 *g *b"
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ß
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

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
Zuletzt geändert von Defnull am Freitag 1. Januar 2010, 20:35, insgesamt 1-mal geändert.
Bottle: Micro Web Framework + Development Blog
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

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?
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Du verwendest ignorecase? Vor der 2 steht eine Nicht-Zahl?
Übrigens: [^0-9] == \D
MfG
HWK

Edit: Zu spät
saltorückwärts
User
Beiträge: 3
Registriert: Freitag 1. Januar 2010, 20:02

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
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

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
Zuletzt geändert von Darii am Freitag 1. Januar 2010, 21:53, insgesamt 1-mal geändert.
saltorückwärts
User
Beiträge: 3
Registriert: Freitag 1. Januar 2010, 20:02

uff... ja, kapiert, vielen dank :wink: hab nur die ersten zwei sätze der funktionsbeschreibung gelesen, das mit den gruppen wird erst im dritten erwähnt :oops:

naja, damit hat sich die sache jedenfalls erledigt :wink:
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Benutze `(?:...)` statt `(...)`.

Stefan
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Darii hat geschrieben: Du willst also vermutlich eher sowas wie G[iga]? verwenden
Was dann auf "G", "Gi", "Gg" und "Ga" matcht? Wohl kaum.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten