Was läuft bei diesem Regexp ab?
Regexphater
- programmiertechnik
0 M.0 T-Rex1 CPAN0 Regexphater0 T-Rex
Hallo,
habe folgende Daten:
aaaaaa,bbbbb,ccccc
wobei aaaa, bbb und ccccc für beliebige Buchstaben stehen.
Nun möchte ich mit einem Regexp folgendes erreichen:
ccccc,bbbbbb,aaaaa
Ich möchte also die Reihenfolge umdrehen.
Folgender Ausdruck 1 funktioniert: (.*?),(.*?),(.*)
Ebenfalls funktioniert 2: (.*),(.*),(.*)
NICHT funktioniert 3: (.*?),(.*?),(.*?)
Meine Frage: müsste nicht bei Ausdruck 2 das erste (.*) bereits die gesamte Zeichenkette matchen und somit eigentlich ein ungewünschstes Ergebnis bringen? Und wieso funktioniert Ausdruck 1 aber nicht Ausdruck 3? Warum macht es einen Unterschied, ob in der letzten Klammer das .* greedy ist oder nicht - danach kommt doch eh nichts relevantes mehr.
Vielleicht kann mir das ja jemand hier erklären.
Viele Grüße!
Bin da auch kein Experte, aber ich versuchs mal. Wenns nicht stimmt, korrigiert mich bestimmt jemand und ich lerne was :)
Ich möchte also die Reihenfolge umdrehen.
Folgender Ausdruck 1 funktioniert: (.*?),(.*?),(.*)
Ebenfalls funktioniert 2: (.*),(.*),(.*)
NICHT funktioniert 3: (.*?),(.*?),(.*?)
Ich würde halt den String am Komma splitten, das Array umdrehen und per Join wieder zusammensetzen. Das aber nur nebenbei, weil ich deine Anwendung nicht kenne.
Meine Frage: müsste nicht bei Ausdruck 2 das erste (.*) bereits die gesamte Zeichenkette matchen und somit eigentlich ein ungewünschstes Ergebnis bringen? Und
IMO nein, da ja "beliebige Zeichen in beliebiger ANzahl bis zum nächsten Komma" gesucht wird.
wieso funktioniert Ausdruck 1 aber nicht Ausdruck 3? Warum macht es einen Unterschied, ob in der letzten Klammer das .* greedy ist oder nicht - danach kommt doch eh nichts relevantes mehr.
Ich sehe das so, dass nach einem String gesucht wird,der beliebige Zeichen in beliebiger ANzahlt enthalten kann. Der Sucht bisa zum Ende. Da nach dem Ende nichts mehr kommt, findet das ? kein zusätzliches Zeichen und somit läuft der Ausdruck ins leere.
ccccc,bbbbbb,aaaaa
Ich möchte also die Reihenfolge umdrehen.
Folgender Ausdruck 1 funktioniert: (.*?),(.*?),(.*)
(.*?) bedeutet, gib mir alles zurück, egal was, gefolgt von einem Egal-Zeichen. Dann soll ein Komma kommen, wobei das Komma das ? Egal-Zeichen sein könnte. Dann soll das gleiche nochmal passieren. Nach dem zweiten Komma kann kommen was will.
Ebenfalls funktioniert 2: (.*),(.*),(.*)
(.*) bedeutet, es kann kommen was will. Dann kommt ein Komma, dann wieder egal was, dann wieder Komma, dann wieder egal. Trifft ebenfalls auf die Zeichenkette zu.
NICHT funktioniert 3: (.*?),(.*?),(.*?)
ähnlich wie bei 1, nur die letzte Anweisung erwartet nach dem aaaa noch ein Egal-Zeichen. Da gibts aber keins mehr. Deshalb wird hier false zurück geliefert.
So interpretier ich das ganze.
Gruß
Der mit der coolen Signatur zur heißen Jahreszeit
T-Rex
ccccc,bbbbbb,aaaaa
Ich möchte also die Reihenfolge umdrehen.
Folgender Ausdruck 1 funktioniert: (.*?),(.*?),(.*)(.*?) bedeutet, gib mir alles zurück, egal was, gefolgt von einem Egal-Zeichen. Dann soll ein Komma kommen, wobei das Komma das ? Egal-Zeichen sein könnte. Dann soll das gleiche nochmal passieren. Nach dem zweiten Komma kann kommen was will.
Okay, danke erstmal, aber: bevor noch weitere Antworten wie von T-Rex und M. kommen, bitte vorher folgendes lesen (ganz am ende des Abschnitts:
https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck#Quantoren
Es geht hier um "greedy" und "nicht greedy". Das Fragezeichen hinter dem * steht dafür, dass "nicht greedy" gesucht werden soll. Es hat hier eine Sonderbedeutung und wird NICHT als "ein beliebiges Zeichen" interpretiert.
NICHT funktioniert 3: (.*?),(.*?),(.*?)
Das ist eine erbärmlich schlechte Problembeschreibung.
> re.pl
$ $_ = 'aaaaaa,bbbbb,ccccc'
aaaaaa,bbbbb,ccccc
$ /(.*?),(.*?),(.*)/
[
[0] "aaaaaa",
[1] "bbbbb",
[2] "ccccc"
]
$ /(.*),(.*),(.*)/
[
[0] "aaaaaa",
[1] "bbbbb",
[2] "ccccc"
]
$ /(.*?),(.*?),(.*?)/
[
[0] "aaaaaa",
[1] "bbbbb",
[2] ""
]
Wie man an der Ausgabe sehen kann, funktioniert №3 sehr wohl. Es gibt bloß nicht zurück, was du erwartest, sondern den leeren String. .*? stimmt überein mit dem leeren String: jedes Zeichen, **null-** oder mehrmal.
Um das erwartete Ergebnis zu bekommen, musst du das Muster am Ende mittels $ verankern.
NICHT funktioniert 3: (.*?),(.*?),(.*?)
Das ist eine erbärmlich schlechte Problembeschreibung.
Aber du hast genau verstanden, was ich meinte ;)
$ /(.*?),(.*?),(.*?)/
[
[0] "aaaaaa",
[1] "bbbbb",
[2] ""
]Wie man an der Ausgabe sehen kann, funktioniert №3 sehr wohl. Es gibt bloß nicht zurück, was du erwartest, sondern den leeren String. .*? stimmt überein mit dem leeren String: jedes Zeichen, **null-** oder mehrmal.
Um das erwartete Ergebnis zu bekommen, musst du das Muster am Ende mittels $ verankern.
Jep, das wars. Jetzt ergibt das ganze Verhalten in meinem Kopf auch einen Sinn. Kriegst einen Keks von mir. =)
Jep, das wars. Jetzt ergibt das ganze Verhalten in meinem Kopf auch einen Sinn. Kriegst einen Keks von mir. =)
Ich hab ihm gesagt was er dir antworten soll, ich will auch einen Keks.
Gruß
cooler als ein eiskaltes Getränk
T-Rex