zwei regex zu einem verbinden

Hallo Gruppe,
ich möchte in einem Text zählen, wieviele Zeichen von '#' oder '0' (XOR) nach einem Punkt folgen. Ich wollte dies mit re.search angehen. Wenn ich entweder auf '#' oder '0' prüfe klappts.
t1 = 'some text .000 more text' t2 = 'some text .### more text'
re.search('.(0*)', t1).groups() >>> ('000',) re.search('.(0*)', t2).groups() >>> ('',) re.search('.(#*)', t1).groups() >>> ('',) re.search('.(#*)', t2).groups() >>> ('###',)
Nun würde ich aber gerne statt zwei regex nur einen haben. Leider bin ich da nicht erfolgreich. Folgendes habe ich schon probiert:
re.search('.(#*)|(0*)', t1).groups() > (None, '') re.search('.(#*)|(0*)', t2).groups() > (None, '') re.search('.(0*)|(#*)', t1).groups() > (None, '') re.search('.(0*)|(#*)', t2).groups() > (None, '') re.search('.(#|0)*', t1).groups() > ('0',) re.search('.(#|0)*', t2).groups() > ('#',) re.search('.(0|#)*', t1).groups() > ('0',) re.search('.(0|#)*', t2).groups() > ('#',) re.search('.(#*|0*)', t1).groups() > ('',) re.search('.(#*|0*)', t2).groups() > ('###',) re.search('.(0*|#*)', t1).groups() > ('000',) re.search('.(0*|#*)', t2).groups() > ('',)
Einen Teilerfolg habe ich mit:
re.search('.(?P<sign>0|[#])(?P<cnt>(?P=sign)*)', t1).groups()
('0', '00')
re.search('.(?P<sign>0|[#])(?P<cnt>(?P=sign)*)', t2).groups()#
('#', '##')
Kann mir jemand sagen, wie das richtig sein muss bzw. wo mein Fehler ist?
Danke, Torsten

Hi
2013/12/18 Torsten P. topic2k@googlemail.com:
Hallo Gruppe,
ich möchte in einem Text zählen, wieviele Zeichen von '#' oder '0' (XOR) nach einem Punkt folgen. Ich wollte dies mit re.search angehen. Wenn ich entweder auf '#' oder '0' prüfe klappts.
t1 = 'some text .000 more text' t2 = 'some text .### more text'
Falls das nur die Fälle sind die in Betracht kommen, würde ich da keine regex für nehmen.
text.count('0') or text.count('#')
Gruß Reimar
re.search('\.(0*)', t1).groups() >>> ('000',) re.search('\.(0*)', t2).groups() >>> ('',) re.search('\.(#*)', t1).groups() >>> ('',) re.search('\.(#*)', t2).groups() >>> ('###',)
Nun würde ich aber gerne statt zwei regex nur einen haben. Leider bin ich da nicht erfolgreich. Folgendes habe ich schon probiert:
re.search('\.(#*)|(0*)', t1).groups() > (None, '') re.search('\.(#*)|(0*)', t2).groups() > (None, '') re.search('\.(0*)|(#*)', t1).groups() > (None, '') re.search('\.(0*)|(#*)', t2).groups() > (None, '') re.search('\.(#|0)*', t1).groups() > ('0',) re.search('\.(#|0)*', t2).groups() > ('#',) re.search('\.(0|#)*', t1).groups() > ('0',) re.search('\.(0|#)*', t2).groups() > ('#',) re.search('\.(#*|0*)', t1).groups() > ('',) re.search('\.(#*|0*)', t2).groups() > ('###',) re.search('\.(0*|#*)', t1).groups() > ('000',) re.search('\.(0*|#*)', t2).groups() > ('',)
Einen Teilerfolg habe ich mit:
re.search('.(?P<sign>0|[#])(?P<cnt>(?P=sign)*)', t1).groups()
('0', '00')
re.search('.(?P<sign>0|[#])(?P<cnt>(?P=sign)*)', t2).groups()#
('#', '##')
Kann mir jemand sagen, wie das richtig sein muss bzw. wo mein Fehler ist?
Danke, Torsten
python-de maillist - python-de@python.org https://mail.python.org/mailman/listinfo/python-de

Hi,
ungetestet, also mit Vorsicht zu genießen:
On Wed, 18 Dec 2013 10:26:42 -0800 (PST) "Torsten P." topic2k@googlemail.com wrote:
ich möchte in einem Text zählen, wieviele Zeichen von '#' oder '0' (XOR) nach einem Punkt folgen. Ich wollte dies mit re.search angehen. Wenn ich entweder auf '#' oder '0' prüfe klappts.
t1 = 'some text .000 more text' t2 = 'some text .### more text'
re.search(r'.([0#]+)', t1)
sollte Dir alle Kombinationen von # und 0 nach einen Punkt zurück liefern. Also (leider) auch wenn "bla.#0##00" steht. Wenn das okay ist, ists hier fertig. Sonst müsste etwas in der Art funktionieren:
re.search(r'.([#0])(\1*)', t1)
das sollte dann ein match liefern, wenn "bla.#blub" oder "bla.0blub" und zwei matches bei "bla.##bla" oder "bla.000000blub".
Viel Spaß mit Perl^H^Hregex!
- Arnold

Fühle mich gerade im Erklärmodus:
On Wed, 18 Dec 2013 10:26:42 -0800 (PST) "Torsten P." topic2k@googlemail.com wrote:
t1 = 'some text .000 more text' t2 = 'some text .### more text' re.search('\.(0*)', t1).groups() >>> ('000',) re.search('\.(0*)', t2).groups() >>> ('',)
Matched Null bis unendlich Nullen, die auf einen Punkt folgen. Das trifft auch auf t2 zu (nach dem Punkt kommen ja null Nullen), darum auch da eine passende MatchGroup.
re.search('\.(#*)', t1).groups() >>> ('',) re.search('\.(#*)', t2).groups() >>> ('###',)
siehe oben
Nun würde ich aber gerne statt zwei regex nur einen haben. Leider bin ich da nicht erfolgreich. Folgendes habe ich schon probiert:
re.search('\.(#*)|(0*)', t1).groups() > (None, '') re.search('\.(#*)|(0*)', t2).groups() > (None, '') re.search('\.(0*)|(#*)', t1).groups() > (None, '') re.search('\.(0*)|(#*)', t2).groups() > (None, '')
Die Pipe außerhalb ist afair einfach eine Pipe. Hier suchst du also nach einem Punkt, dann null oder mehr Rauten bzw. Nullen, dann eine Pipe, dann null oder mehr Nullen bzw. Rauten. Da Deine Beispiele keine Pipe enthalten, wird nix gematcht.
re.search('\.(#|0)*', t1).groups() > ('0',) re.search('\.(#|0)*', t2).groups() > ('#',) re.search('\.(0|#)*', t1).groups() > ('0',) re.search('\.(0|#)*', t2).groups() > ('#',)
Fast das, was Du wolltest :-) Nur das das Sternchen nach der Matchgroup nicht die gewünschte Wirkung hat.
re.search('\.(#*|0*)', t1).groups() > ('',) re.search('\.(#*|0*)', t2).groups() > ('###',) re.search('\.(0*|#*)', t1).groups() > ('000',) re.search('\.(0*|#*)', t2).groups() > ('',)
Hier suchst Du einen Punkt gefolgt von null oder mehr Rauten oder null oder mehr Nullen. Da das jeweils erste davon gefunden wird (.# ist schließlich ein Punkt gefolgt von null Nullen) gibt es nicht Dein Wunschergebnis.
In dem Email eben hab ich ja schon eine Idee geäußert, die Dein Ergebnis liefern dürfte...
- Arnold

Am 18.12.2013 21:04, schrieb Arnold Krille:
re.search('\.(#*)|(0*)', t1).groups() > (None, '') re.search('\.(#*)|(0*)', t2).groups() > (None, '') re.search('\.(0*)|(#*)', t1).groups() > (None, '') re.search('\.(0*)|(#*)', t2).groups() > (None, '')
Die Pipe außerhalb ist afair einfach eine Pipe. Hier suchst du also nach einem Punkt, dann null oder mehr Rauten bzw. Nullen, dann eine Pipe, dann null oder mehr Nullen bzw. Rauten. Da Deine Beispiele keine Pipe enthalten, wird nix gematcht.
Nöö,es gibt kein "Pipe außerhalb". Die Regexp "A|B" matcht "A" oder "B".
Die ersten beiden dieser Pattern matchen also entweder - einen Punkt gefolgt von beliebig vilelen Hask-Marks, oder - beliebig viele Nullen. Denn es fehlen die Klammer, die angeben, auf was sich das Pipe bezieht. Und damit "teilt" es das komplette Pattern.

Am Thu, 19 Dec 2013 10:28:53 +0100 schrieb Hartmut Goebel h.goebel@goebel-consult.de:
Am 18.12.2013 21:04, schrieb Arnold Krille:
re.search('\.(#*)|(0*)', t1).groups() > (None, '') re.search('\.(#*)|(0*)', t2).groups() > (None, '') re.search('\.(0*)|(#*)', t1).groups() > (None, '') re.search('\.(0*)|(#*)', t2).groups() > (None, '')
Die Pipe außerhalb ist afair einfach eine Pipe. Hier suchst du also nach einem Punkt, dann null oder mehr Rauten bzw. Nullen, dann eine Pipe, dann null oder mehr Nullen bzw. Rauten. Da Deine Beispiele keine Pipe enthalten, wird nix gematcht.
Nöö,es gibt kein "Pipe außerhalb". Die Regexp "A|B" matcht "A" oder "B".
Die ersten beiden dieser Pattern matchen also entweder
- einen Punkt gefolgt von beliebig vilelen Hask-Marks, oder
- beliebig viele Nullen.
Denn es fehlen die Klammer, die angeben, auf was sich das Pipe bezieht. Und damit "teilt" es das komplette Pattern.
Ah, danke. Hat mein schnupfenumnebeltes Gehirn was gelernt.
- Arnold

Am Wed, 18 Dec 2013 10:26:42 -0800 (PST) schrieb "Torsten P." topic2k@googlemail.com:
re.search('\.(#*|0*)', t1).groups() > ('',) re.search('\.(#*|0*)', t2).groups() > ('###',)
Das ist nahe dran. Aber re.search macht bei '(A|B)' Feierabend, sobald A passt, auch wenn B einen längeren Treffer ergeben würde. Und '#*' passt halt auch für 'kein #'.
Nimm daher statt '*' ein '+':
re.search(r'.(0+|#+)', t1).groups()
('000',)
re.search(r'.(0+|#+)', t2).groups()
('###',)
Wenn weder '0' noch '#' nach dem '.' kommen, bekommst du eine Exception:
re.search('.(#+|0+)', 'some text .aaa more text').groups()
Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'groups'
Wenn du statt dessen lieber einen leeren Treffer willst, kannst du die Gruppe mit '?' optional machen:
re.search('.(#+|0+)?', 'some text .aaa more text').groups()
(None,)
participants (5)
-
Arnold Krille
-
Florian Diesch
-
Hartmut Goebel
-
Reimar Bauer
-
Torsten P.