[gelöst] RegExp - mehrere Treffer in einer Zeile

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
Igor
User
Beiträge: 8
Registriert: Donnerstag 15. Februar 2007, 13:16

Donnerstag 15. Februar 2007, 13:22

hallo zusammen :-)

Ich hab ein Problem mit RegExp (re).

In aller Kürze:

Code: Alles auswählen

import re
m = re.findall("x(.*)x", "x1x x2x x3x")
print m
Das Ergebnis ist => ['1x x2x x3'] was ja irgentwie schon richtig ist. Was ich möchte ist aber ein ['1', '2', '3']. Ich hab schon mit den Flags rumgespielt, aber leider keinen Erfolg gehabt.

Gibts da einen Trick?

Eins vorweg: "x(.)x" klappt nicht, da dieser RegExp nur ein Beispiel für mein Problem ist.

Danke für die Hilfe und Grüße an alle!

igor :-)
Zuletzt geändert von Igor am Donnerstag 15. Februar 2007, 14:10, insgesamt 1-mal geändert.
BlackJack

Donnerstag 15. Februar 2007, 13:38

Reguläre Ausdrücke versuchen immer soviel wie möglich zu matchen. Das heisst (.*) hört nach der 1 nicht auf, sondern nimmt auch noch den ganzen Rest mit in den ersten Treffer.

Entweder Du schränkst das Muster ein, im Beispiel würden sich Ziffern anbieten, oder Du sagst, dass das * nicht "greedy" (gierig) sein soll:

Code: Alles auswählen

In [17]: re.findall("x(.*?)x", "x1x x2x x3x")
Out[17]: ['1', '2', '3']
Igor
User
Beiträge: 8
Registriert: Donnerstag 15. Februar 2007, 13:16

Donnerstag 15. Februar 2007, 13:41

hallo,

danke für die schnelle Antwort.

Das einschränken auf Ziffern klappt nicht, weil wie gesagt, diese RegExp nur ein beispiel für das Problem ist.

Die Fragezeichenlösung werde ich mal testen!

Danke für die gute hilfe!

Grüße

igor :-)
Igor
User
Beiträge: 8
Registriert: Donnerstag 15. Februar 2007, 13:16

Donnerstag 15. Februar 2007, 14:10

Sieht gut aus!

Besten Dank für die schnelle und gute Hilfe!

War meine erste Frage hier, und ich bin sehr überrascht wie schnell das Problem gelöst ist!

Super!

Grüße

igor :-)
PmanX
User
Beiträge: 123
Registriert: Donnerstag 25. Januar 2007, 13:50
Wohnort: Germany.BB.LOS
Kontaktdaten:

Donnerstag 15. Februar 2007, 17:07

Code: Alles auswählen

>>> import re
>>> m = re.findall(r'x([^x]+)x', "x1x x2x x3x")
>>> m
['1', '2', '3']
Oft ist es eindeutiger, eine negierte Zeichenklasse zu verwenden.
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Donnerstag 15. Februar 2007, 17:54

Es ist auch schneller, auch wenn man das wohl meistens vernachlässigen kann, wenn es nicht gerade besonders oft in einer Schleife aufgerufen wird.
Ich würde dennoch die Negation bevorzugen, da damit expliziter angegeben wird, was gesucht ist.
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
PmanX
User
Beiträge: 123
Registriert: Donnerstag 25. Januar 2007, 13:50
Wohnort: Germany.BB.LOS
Kontaktdaten:

Donnerstag 15. Februar 2007, 18:06

Luzandro hat geschrieben:Es ist auch schneller, auch wenn man das wohl meistens vernachlässigen kann, wenn es nicht gerade besonders oft in einer Schleife aufgerufen wird.
Ich würde dennoch die Negation bevorzugen, da damit expliziter angegeben wird, was gesucht ist.
Warum sprichst Du Performance an, ohne einen Beweis zu liefern?
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Donnerstag 15. Februar 2007, 18:24

Code: Alles auswählen

>>> import re, timeit
>>> input = "x"+ "XXX"*666 + "x"
>>> p1 = re.compile("x([^x]+)x")
>>> p2 = re.compile("x(.+?)x")
>>> timeit.Timer("p1.search(input)", "from __main__ import p1, input").timeit()
3.76698899269104
>>> timeit.Timer("p2.search(input)", "from __main__ import p2, input").timeit()
139.78905892372131
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Freitag 16. Februar 2007, 11:45

habe das gerade mal nachgestellt:

Code: Alles auswählen

>>> import re, timeit
>>> input='x'  'XXX'*666 + 'x'
>>> p1=re.compile('x([^x]+)x')
>>> p2=re.compile('x(.+?)x')
>>> len(input)
2665
>>> timeit.Timer('p1.search(input)','from __main__ import p1, input').timeit()
4.2838837555154434
>>> timeit.Timer('p2.search(input)','from __main__ import p2, input').timeit()
4.6004806939430392
>>>
Das ganze auf einem Dual-P-III (1 GHz) mit 512 MB unter Windows XP, Python Version 2.4.3, python-shell (CLI) frisch gestartet.
Ich sehe da nicht so den Unterschied.

querdenker
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Freitag 16. Februar 2007, 11:56

querdenker hat geschrieben:habe das gerade mal nachgestellt:

Code: Alles auswählen

>>> import re, timeit
>>> input='x'  'XXX'*666 + 'x'
Du hast einen anderen input: das *666 bezieht sich bei dir auf den String "xXXX" und damit gibt es viel früher einen Match.
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Freitag 16. Februar 2007, 15:09

Damned Typo!
Habe es gerade gesehen. Teste es gerade nochmal und komme jetzt auch auf ein Verhalten gleich deinem.

Schönes Wochenende, querdenker
Antworten