Suche regex...

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
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

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
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo mutetella,

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

Grüße
Sirius
lunar

@mutetella

Code: Alles auswählen

names = '|'.join(re.escape(n) for n in ('title', 'begin', 'owner'))
pattern = re.compile(r'^((?:{0})=)?(.*)$'.format(names))
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@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
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@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.
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.
Jasmina
User
Beiträge: 10
Registriert: Sonntag 4. November 2012, 15:05

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
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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 '\'?
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@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?
Jasmina
User
Beiträge: 10
Registriert: Sonntag 4. November 2012, 15:05

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.

:?: :?: :?:
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.
Jasmina
User
Beiträge: 10
Registriert: Sonntag 4. November 2012, 15:05

@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 :) )
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Beispiel:

Code: Alles auswählen

>>> text="abc:def:ghi"
>>> re.match('^\w+:(\w+):',text).group(1)
'def'
Jasmina
User
Beiträge: 10
Registriert: Sonntag 4. November 2012, 15:05

: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*
Antworten