Seite 1 von 1

Problem mit (...)?

Verfasst: Freitag 1. Januar 2010, 20:18
von saltorückwärts
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ß

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 :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:

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.