Seite 1 von 1

Suche regex...

Verfasst: Donnerstag 20. Dezember 2012, 10:09
von mutetella
Hallo,

ich habe folgendes:

Code: Alles auswählen

>>> name_pattern = '|'.join(('title', 'begin', 'owner'))
>>> re.match(r'({0}=)?(.*)'.format(name_pattern), 'title=bla').groups()
('title', '=bla')
Als Ergebnis hätte ich allerdings gerne

Code: Alles auswählen

('title=', 'bla')
Egal was ich mit dem '=' anstelle, ich bekomm's nicht hin... :(

mutetella

Re: Suche regex...

Verfasst: Donnerstag 20. Dezember 2012, 10:17
von Sirius3
Hallo mutetella,

schau Dir mal an, wie Dein fertiger regulärer Ausdruck aussieht.
Tipp: bei 'owner=bla' funktionierts.

Grüße
Sirius

Re: Suche regex...

Verfasst: Donnerstag 20. Dezember 2012, 10:21
von lunar
@mutetella

Code: Alles auswählen

names = '|'.join(re.escape(n) for n in ('title', 'begin', 'owner'))
pattern = re.compile(r'^((?:{0})=)?(.*)$'.format(names))

Re: Suche regex...

Verfasst: Donnerstag 20. Dezember 2012, 10:59
von mutetella
@Sirius3
Ja, schon klar, allerdings hätte ich ja dann

Code: Alles auswählen

name_pattern = r'{0}='.format('=|'.join(attr_names), '=')
machen müssen, und wenn ich sowas seh', dann muss was faul sein... :) Oder denkst Du, das ginge ohne Gelächter durch (keine rhetorische Frage!)?

@lunar
Vielen Dank! Soweit ...

Code: Alles auswählen

re.match(r'(({0})=)?(.*)'.format(name_pattern), arg)
... hatte ich es auch bereits versucht, bekam aber immer eine neue Gruppe. Und zu meiner Verteidigung: Doch, ich habe die Doku gelesen! :D Allerdings fand ich die Erklärung zu (?:...) dermaßen hirrli wirrli, dass ich sofort beschloss: Das ist nicht, was ich suche! :mrgreen:

Was ich an Deiner Lösung noch nicht verstehe:
  • Warum schickst Du die Namen an 're.escape'? Eigentlich bräuchte es doch nicht einmal das r-Flag, oder?
  • Warum setzt Du das Zeilenbeginn und -ende? 're.match' durchsucht doch grundsätzlich von Anfang (bis Ende?)?
  • Hat das vorab Kompilieren auch in meinem Fall einen Vorteil oder wolltest Du damit nur Deine Lösung auf das pattern verallgemeinern?
mutetella

Re: Suche regex...

Verfasst: Donnerstag 20. Dezember 2012, 11:08
von Sirius3
@mutetella: ich wußte nicht, was Du alles schon versucht hattest.

1. Strings, die in einen regulären Ausdruck eingehen, sollte man prinzipiell immer escapen.
2. re.match prüft ab Anfang des Strings, aber nicht bis zum Schluß. Je nach Anwendungsfall
fände ich es problematisch ^ und $ in einen compilierten Pattern aufzunehmen, da es ja
search und finditer verhindert.
3. vorkompilieren hat den Vorteil, dass man an Pattern-Objekt hat, was meistens besser lesbar ist.

Re: Suche regex...

Verfasst: Donnerstag 20. Dezember 2012, 11:18
von lunar
@mutetella Aus Deinem Beitrag geht nicht hervor, woher diese Namen kommen, und ob sichergestellt ist, dass in einzelnen Namen niemals Sonderzeichen regulärer Ausdrücke vorkommen. Um sicherzugehen, maskiere ich die Namen.

Durch die explizite Angabe der Zeilengrenzen wird das Muster eindeutig, egal mit welcher Methode man es verwendet. Gestalte Muster möglichst eindeutig, um Fehler oder falsche Eingaben zuverlässig zu erkennen. Dazu gehört in Deinem Fall auch die Angabe des Anfangs und des Endes des gesuchten Texts.

Ob das Kompilieren einen Vorteil hat, hängt davon ab, wie Du das Muster verwendest. Grundsätzlich werden Muster vor der Verwendung immer kompiliert. Wenn Du das Muster als Text übergibst, geschieht das halt intern in der entsprechenden "re"-Funktion. Insofern schadet das Kompilieren nicht. Im Idealfall kompilierst Du das Muster einmal und bindest es an eine Konstante auf Modul- oder Klassenebene.

@Sirius3 Von "re.search()" und "re.finditer()" hat niemand gesprochen. mutetella verwendet "re.match()", ist also ohnehin mindestens am Zeilenanfang interessiert. Die Zeilengrenzen sind also wohl relevant für das Ergebnis der Suche, und gehören daher ins Muster, anstatt sie nur implizit über die richtige Methode vorauszusetzen.

Re: Suche regex...

Verfasst: Freitag 22. Februar 2013, 20:05
von Jasmina
Hallo zusammen,

ich bin auch auf der Suche nach einem Regex und hoffe, dass ich hier richtig gelandet bin. Mit Regex hab ich erst angefangen und hab daher noch nicht so sehr den Durchblick. Ich habe folgende Zeile:

Code: Alles auswählen

7\Aas\6\'as\[a:s]\'as\[a:s]
und möchte nur das Aas, aber ohne \ davor und danach.

Jetzt gibt mir der Regex:

Code: Alles auswählen

(\\s*(\D*)\s*\\)
nur \Aas\ raus. (Hab ich bei regexpal getestet). Auch nach rumprobieren bekomm ich es nicht hin, das die \ verschwinden. Kann mir da jemand einen Tipp geben?

Viele Grüße
Jasmina

Re: Suche regex...

Verfasst: Freitag 22. Februar 2013, 20:19
von cofi
Jasmina hat geschrieben:ich bin auch auf der Suche nach einem Regex und hoffe, dass ich hier richtig gelandet bin.
Nein, bitte erstell in Zukunft ein neues Thema fuer ein neues Problem. Das alte Thema weiterfuehren spart nichts, sondern stiftet nur Verwirrung - gerade bei Leuten, die die Themen durchsuchen.

Nun, wenn du 'Aas' matchen willst, ist 'Aas' die passende RE, welches allgemeine Muster willst du denn matchen? Alles zwischen zwei '\'?

Re: Suche regex...

Verfasst: Freitag 22. Februar 2013, 22:26
von Sirius3
@Jasmina: ist der reguläre Ausdruck in einem Rawstring r"(\\s*(\D*)\s*\\)" oder nicht?

Falls ja, weil Du sonst nicht das Ergebnis \Aas\ als erste Gruppe und Aas als zweite Gruppe bekommen würdest, übersetze ich Dir mal Deinen Ausdruck nach deutsch:
suche den Teilstring der aus Folgenden Teilen besteht:
1. ein \
2. eine beliebige Anzahl an „s“
3. eine beliebige Anzahl an Zeichen, die keine Ziffern sind
4. eine beliebige Anzahl an Leerzeichen, Tabs, newlines etc.
5. ein \
dabei werden zwei Gruppen gebildet: erstens der gesamte Suchtext (was überflüssig ist, da über group(0) ermittelbar) und zweitens nur die Zeichen unter 3.

Also schließe ich mich cofis Frage an: Was willst Du matchen?

Re: Suche regex...

Verfasst: Samstag 23. Februar 2013, 11:32
von Jasmina
Dann mach ich nächstes Mal ein neues Thema auf, um Verwirrungen aus dem Weg zu gehen. :oops:

@Sirius3: Jepp, der raw-string sähe so aus.

Es ist so. Ich habe eine ganze Liste:

Code: Alles auswählen

13\abaenderlich\0\'...
14\Abaenderung\17\'&p...
15\Abandon\0\&-bq-'d~\...
...
und ich will NUR alle richtigen Worte matchen, ohne \ und dem restlichen Kladeradatsch.
abaenderlich, Abaenderung, Abandon....
Das hier reicht ja eigentlich auch schon, um bspw. \abaenderlich\ rauszubekommen (hab nochmal ein bisschen rumprobiert).

Code: Alles auswählen

(\\(\D*)\\)
Aber diese doofen \ sind halt noch drin.

:?: :?: :?:

Re: Suche regex...

Verfasst: Samstag 23. Februar 2013, 11:43
von BlackJack
@Jasmina: Wo sind die drin? In der äusseren Gruppe sind sie natürlich enthalten — Du hast sie dort ja explizit reingeschrieben. Aber in der inneren Gruppe sollten sie nicht enthalten sein. Also lass entweder die äussere Gruppe weg, von der sehe ich jetzt den Sinn sowieso nicht, oder passe den Gruppenzugriff entsprechend an.

Man könnte den Ausdrück auch etwas spezifischer machen wenn das gesuchte Wort immer zwischen dem ersten und zweiten '\' in einer Zeile kommt. So wie er jetzt da steht muss man ja ein `search()` oder `findall()` statt eines `match()` verwenden. Vielleicht könnte man sich reguläre Ausdrücke hier sogar komplett sparen und die `split()`-Methode auf Zeichenketten verwenden.

Re: Suche regex...

Verfasst: Samstag 23. Februar 2013, 17:15
von Jasmina
@BlackJack: Stimmt, die Worte kommen immer zwischen dem ersten '\' und dem zweiten '\' vor, so langsam seh ich den Wald vor lauter Bäumen nicht mehr. Wie mach ich den Ausdruck denn in der Hinsicht spezifischer? Ich hab einen totalen regex Knoten im Gehirn :?

Das es für eine Abschlussarbeit in einem Kurs ist, sollten schon regex mit drin sein (auch wenn man das ohne machen könnte :) )

Re: Suche regex...

Verfasst: Samstag 23. Februar 2013, 17:38
von Sirius3
Beispiel:

Code: Alles auswählen

>>> text="abc:def:ghi"
>>> re.match('^\w+:(\w+):',text).group(1)
'def'

Re: Suche regex...

Verfasst: Dienstag 26. Februar 2013, 19:38
von Jasmina
:mrgreen:

An alle vielen Dank!!! Jetzt versteh ich das alles deutlich besser!

@ Sirius3: Danke für den Tipp. Es klappt :D

Einen schönen Abend an alle
Jasmina

*hüpf*