Seite 1 von 1
Probleme mit Regex
Verfasst: Montag 27. Februar 2012, 21:53
von HPL
Code: Alles auswählen
p1 = re.compile('@relationS\*\s*@data', re.IGNORECASE)
print re.match(p1, text).group()
Habe p1 als Regex.
text ist ein String, der mit "@relation" beginnt und mit "@data" enthält, zwischen @relation und @data kommen alle möglichen Buchstaben vor, auch Leerzeichen und " ".
Ich will nun den Text von Relation bis @data print re.match(p1, text).group() ausdrucken, group() soll ja angeblich einen String hergeben.
Fehler lautet:
print re.match(p1, text).group()
Attribute Error: 'NoneType' object has no attribute 'group'
Aus der Doku werd ich nicht schlau. Hat jemand ne ID? Hab ich die Regex zu blöd geschrieben?
mit \S*\s* wollte ich sagen: entweder ein non-whitespace oder ein whitespace kommt jeweils(!) beliebig oft.
Ich habe es auch schon mit der Wildcard .* versucht (auch so: \,*). Is nix zu wollen.

Re: Probleme mit Regex
Verfasst: Montag 27. Februar 2012, 22:01
von nomnom
Deine Regex ist kaputt. Deine jetzige sucht nach „@relationS*“ gefolgt von beliebig viel Whitespace und „@data“.
Was du willst ist:
Code: Alles auswählen
In [2]: DATA = '@relation spam spam spam @data'
In [3]: pattern = re.compile('@relation(.*)@data')
In [4]: pattern.findall(DATA)
Out[4]: [' spam spam spam ']
In meiner Regex mache ich Gebrauch von „Gruppen“. So fasse ich alle Zeichen zwischen den Klammern zusammen, sodass ich diese als Ergebnis von `pattern.findall(...)` erhalte.
Reguläre Ausdrücke sollte man in Python übrigens als
Rawstrings schreiben. Dann werden Backslashes anders behandelt.
Code: Alles auswählen
In [5]: '\b'
Out[5]: '\x08'
In [6]: r'\b'
Out[6]: '\\b'
Re: Probleme mit Regex
Verfasst: Montag 27. Februar 2012, 22:04
von BlackJack
@HPL: Die `match()`-Funktion gibt `None` zurück wenn das Muster nicht auf den Text passt, und das `None`-Objekt hat keine `group()`-Methode. Deshalb die Ausnahme.
Im Quelltext steht 'S\*\s*', im Text dagegen '\S*\s*'!? Gib doch mal ein komplettes Beispiel an. Also auch einen oder mehrere Beispieltexte auf welche die `match()`-Funktion angewendet werden soll.
'\S*\s*' bedeutet übrigens 0 oder mehr nicht-whitespace *gefolgt* von 0 oder mehr whitespace Zeichen und nicht das eine *oder* das andere. Wenn das eigentlich nicht-whitespace oder whitespace und davon beliebig viele (inklusive keine) bedeuten sollte, dann wäre ein Wildcard '.*' tatsächlich die kürzere und einfacherere Art das auszudrücken.
Re: Probleme mit Regex
Verfasst: Montag 27. Februar 2012, 23:06
von sma
Damit "." auch auf Zeilenumbrüche reagiert (was "\s" machen würde) muss noch re.DOTALL gesetzt werden.
Stefan
Re: Probleme mit Regex
Verfasst: Montag 27. Februar 2012, 23:48
von HPL
Und wenn er nun beliebig viele beliebige Zeichen, die von einem Komma gefolgt werden, 4 mal matchen soll, also z. B. sdfsdf,43543gfg, 333, hjkö,
Kann ich das dann als [(*),]{4} ?
Dieser Versuch war bei mir näml. von keinem großen Erfolg gekrönt :K
Re: Probleme mit Regex
Verfasst: Dienstag 28. Februar 2012, 00:04
von BlackJack
@HPL: Wie kommst Du denn auf eckige Klammern dafür? Und worauf bezieht sich der '*' in dem Ausdruck? Du musst schon die Dokumentation lesen und verstehen und nicht einfach wild irgend etwas ausprobieren was so ähnlich wie ein regulärer Ausdruck aus sieht.
Re: Probleme mit Regex
Verfasst: Dienstag 28. Februar 2012, 00:13
von webspider
Ich wette der folgende Verbesserungsvorschlag wäre eines Code-Golf-Wettbewerbs würdig.
edit: Wobei man auch einfach den fraglichen String auf die Anzahl der Kommata prüfen könnte.
Re: Probleme mit Regex
Verfasst: Dienstag 28. Februar 2012, 08:59
von BlackJack
@webspider: Die äusseren Klammern definieren eine unnötige Gruppe, weil der komplette Treffer immer Gruppe 0 ist. Die man auch bekommt wenn man die `group()`-Methode ohne Argument aufruft.
Dafür sollte man noch ein '?' verwenden um '*' „non-greedy” zu machen, und damit unnötiges „backtracking” bei der Suche vermeiden.
Re: Probleme mit Regex
Verfasst: Dienstag 28. Februar 2012, 10:06
von webspider
Ach so ist das. Du meinst also, dass bevor der Treffer "123, 345, abc, xyz," (der das erste Ergebnis einer gierigen Suche wäre) verworfen wird, dieser nochmals vom Inhalt her untersucht wird auf passende Teilstrings (was komplexer wäre als auf die ungierige Weise direkt nach den kleinstmöglichen Treffern zu suchen). Gut, das mit den Klammern war schon offensichtlicher gewesen
Re: Probleme mit Regex
Verfasst: Dienstag 28. Februar 2012, 17:30
von sma
Will man das letzte Komma wirklich haben? Falls nein, würde ich ".*?(?:,.*?){3}" als effiziente Variante empfehlen.
Stefan
Re: Probleme mit Regex
Verfasst: Dienstag 28. Februar 2012, 18:45
von nomnom
sma hat geschrieben:Will man das letzte Komma wirklich haben? Falls nein, würde ich ".*?(?:,.*?){3}" als effiziente Variante empfehlen.
Ich würde gar keinen regulären Ausdrück dafür empfehlen. Eher das:
Es ist kürzer und schneller … (Okay, drei Mikrosekunden Unterschied ist wohl nicht so enorm …)