Dach- und Dollar-Operator in Regex

Phoenixz

Lieutenant
Registriert
März 2004
Beiträge
595
Hallo,

Ohne große ausschweife komme ich gleich auf meine Frage zu sprechen. Für ein aktuelles Projekt würde ich mir gerne von euch zwei Vermutungen bestätigen lassen bezüglich des ^-Operators und der $-Operators.

(1) Wenn es wirklich immer nur darum geht, dass ich wissen will ein kompletter Text z.B. „abc$“ matched, dann kann ich das „$“ auch immer gleich weglassen, da ich ja nicht wissen will ob es in dem Text einen match gibt sondern ob der komplette Text ein match ist? Beispiel: Text = „abc“ würde matchen, hingegen „yxcabc“ würde nicht matchen (zumindest nicht der komplette Text). Gleiches gilt auch für den ^-Operator.
(2) Ist „abc$de“ ein gültiger Regex? Den für mich macht das irgendwie keinen Sinn, genau wie „abc^de“. Der Dach-Operator muss doch immer am Anfang stehen und der Dollar-Operator am Ende? Jedoch wird das bisher von keinem Regex "Interpreten" als fehlerhaften Regex ausgeworfen. Warum? Ist der doch gültig?

Das wars auch schon, vielen Dank,
Daniel
 
(1) Je nach Regex-Interpreter geht es bei "abc" aber nicht darum, dass der komplette String trifft, sondern es reicht dann, dass "abc" im String vorkommt...

(2) Ist "if (false)" ein gültiger Ausdruck? Den für mich macht das irgendwie keinen Sinn, genau wie "while (false)". ...
Nur weil etwas offensichtlich sinnlos ist, heißt es nicht, dass es auch syntaktisch falsch sein muss...
 
1) Wenn auf den kompletten String geprüft wird, dann ja (also ein match im Gegensatz zu einem find)

2) Der Ausdruck ist gültig. Eine sinnvolle Anwendung kommt mir allerdings nicht in den Sinn. Um das Dollarzeichen zu matchen, muss man escapen.
 
1.

abc$ matcht nur, wenn abc am Ende steht. -> Trifft also xyabc, aber nicht xabcy oder abcxy.
abc matcht alles, was abc enthält. -> Trifft abcxy, xabcy, sowie yxabc
^abc match abc am Anfang des Strings. -> Trifft abcxy, aber nicht xabcy oder xyabc.

Siehe aber auch 1668mibs Einwand, je nachdem wie der Interpreter es auffast, kann es auch ein [abc]$ sein. ^ und $ sind auch nur gültig, wenn der m-Modifier gesetzt ist.

2. Semantik wie auch schon 1668mib sagte. (abc$|de) wäre deiner Meinung nach ungültig, ist er aber nicht.
 
Ich habe es auch eher verstanden wie soares. Man muss unterscheiden zwischen match und find. Daher matched abc$ NICHT xabc (also nicht die komplette Zeichenfolge. Auch zu sehen hier: regexpal.com/). Hingegen würde .*abc$ schon (die komplette Zeichenfolge) xabc (und auch xyzabc) matchen.
In meinem Kontext interessiert mich nur ein (full-)match. Daher ist glaube ich die Angabe von $ oder ^ irrelevant (in meinem speziellen Kontext).

Vielen Dank nochmal für die Antworten!
 
Es kommt halt auf die Implementierung an. java.util.regex. z.B. bietet explizit ein match() und ein find() zum Anwenden eines Regex an. Wenn dort match() verwendet wird, kann man ^$ weglassen. Bei find() würden sie benötigt.
 
Du matchst doch aber trotzdem. Wenn du abc$ hast, matcht er eben abc am Ende. Wenn du .*abc$ matcht, matcht er die komplette Zeile, wo abc am Ende steht. Das drückst du doch eben mit .* aus, dass vor abc am Ende noch etwas anderes kommen darf. Ist doch logisch, dass er somit auch xabc und yxabc (am Ende) matcht. Du kannst auch .*(abc)$ matchen, wodurch du eine Backreference auf abc hättest und dieses auch in Programmiersprachen herausziehen kannst.

Wahrscheinlich verstehe ich nur dein Anliegen nicht ganz. :)
 
Mit match() (in Java) wird immer der komplette String getestet. Deswegen kann man hier ^$ weglassen. Nur um diesen Fall geht es. Das Matchen funktioniert in diesem Fall also nicht zeilenweise!
 
@ soares:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/Matcher.html#find%28%29 schrieb:
find

public boolean find()

Attempts to find the next subsequence of the input sequence that matches the pattern.

This method starts at the beginning of the input sequence or, if a previous invocation of the method was successful and the matcher has not since been reset, at the first character not matched by the previous match.

If the match succeeds then more information can be obtained via the start, end, and group methods.

Returns:
true if, and only if, a subsequence of the input sequence matches this matcher's pattern
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/Matcher.html#matches%28%29 schrieb:
matches

public boolean matches()

Attempts to match the entire input sequence against the pattern.

If the match succeeds then more information can be obtained via the start, end, and group methods.

Returns:
true if, and only if, the entire input sequence matches this matcher's pattern
find() und matches() sind aber zwei unterschiedliche Sachen.

matches() und abc sollte alle abc matchen, genauso wie bei find() und abc alle abc gefunden werden sollten. Genauso sollte abc$ bei matches() und find() das Gleiche zurückgeben. Ich hab kaum mit Java zu tun (bin C bewandert), aber je nachdem wie matches() eingebunden ist, sollte es irgendwie per (abc) alle Matches von abc zurückgeben. Das Gleiche würdest du per Schleife und find() machen.
 
Yuuri schrieb:
find() und matches() sind aber zwei unterschiedliche Sachen.

Genau darum geht es dem TE doch!

Yuuri schrieb:
matches() und abc sollte alle abc matchen, genauso wie bei find() und abc alle abc gefunden werden sollten. Genauso sollte abc$ bei matches() und find() das Gleiche zurückgeben. Ich hab kaum mit Java zu tun (bin C bewandert), aber je nachdem wie matches() eingebunden ist, sollte es irgendwie per (abc) alle Matches von abc zurückgeben. Das Gleiche würdest du per Schleife und find() machen.

Nein, der Unterschied ist, dass matches() prüft, ob der Regex den kompletten String matcht. Z.B. beim Regex "abc" würde der String "abc" matchen. "abcabc" aber nicht!

find() hingegen findet den nächsten Match (abhängig von der aktuellen Position im Matcher-Objekt). Damit kann man mehrere Matches finden. Hier würden bei meinem Beispiel beide Strings einen Match liefern.

Deswegen habe ich in meinem ersten Post die Einschränkung match() vs. find() gemacht. Es kommt eben auf die Implementierung an. Java war hier nur als ein konkretes Beispiel angeführt.
 
find() kannst du doch aber mit (abc) matches() umsetzen, was dir alle Vorkommen von abc zurück gibt im kompletten String. Darum gehst mir ja jetzt hier. Ist halt eine Implementierungsfrage wie du sagtest, hat aber mit regulären Ausdrücken per se nichts zu tun. ;)
 
Yuuri schrieb:
find() kannst du doch aber mit (abc) matches() umsetzen,

Mit der Java-Implementierung nicht!

Yuuri schrieb:
was dir alle Vorkommen von abc zurück gibt im kompletten String.

Die Java-Implementierung von matches() prüft, ob input == regex, also z.B. ob "abc" == "abc" ist. Anders ausgedrückt, wenn der Input nicht gleich "abc", wird matches() immer False liefern.

Funktioniert mit Python z.B. ähnlich. C hat keinen Regex-Support eingebaut. Da suchst Du Dir halt die Library, die Dir gefällt.


Yuuri schrieb:
Darum gehst mir ja jetzt hier.

Dann mach einen eigenen Thread auf :D Die Frage des TE war eine andere und sollte hoffentlich geklärt sein.
 
Ja, vielen Dank! Meine Frage ist definitiv geklärt!
 
Zurück
Oben