Seite 1 von 1

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

Verfasst: Donnerstag 15. Februar 2007, 13:22
von Igor
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 :-)

Verfasst: Donnerstag 15. Februar 2007, 13:38
von BlackJack
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']

Verfasst: Donnerstag 15. Februar 2007, 13:41
von Igor
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 :-)

Verfasst: Donnerstag 15. Februar 2007, 14:10
von Igor
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 :-)

Verfasst: Donnerstag 15. Februar 2007, 17:07
von PmanX

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.

Verfasst: Donnerstag 15. Februar 2007, 17:54
von Luzandro
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.

Verfasst: Donnerstag 15. Februar 2007, 18:06
von PmanX
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?

Verfasst: Donnerstag 15. Februar 2007, 18:24
von Luzandro

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

Verfasst: Freitag 16. Februar 2007, 11:45
von querdenker
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

Verfasst: Freitag 16. Februar 2007, 11:56
von Luzandro
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.

Verfasst: Freitag 16. Februar 2007, 15:09
von querdenker
Damned Typo!
Habe es gerade gesehen. Teste es gerade nochmal und komme jetzt auch auf ein Verhalten gleich deinem.

Schönes Wochenende, querdenker