Reguläre Ausdrücke: string.matches() und gefangene Gruppen

Crian

Top Contributor
Ich frage mich gerade, ob es nach

Java:
String string = "Nur ein Beispiel-Text.";
if (string.matches(".*(ein).*(Text).*") {
    String ein = ...;
}

eine Möglichkeit gibt, an die gefangene Gruppe zu kommen, oder ob das zwingend nur per


Java:
String string = "Nur ein Beispiel-Text.";
Pattern pattern = Pattern.compile(".*(ein).*(Text).*");
Matcher matcher = pattern.matcher(string);
if (matcher.matches() {
    String ein = matcher.group(1);
}

geht.
 
Mit erster Variante kann man nur prüfen, ob ein String einem bestimmten Muster entspricht.
Mit zweiter Variante kann man einen String anhand eines Musters zerlegen. Ob ein Code hässlich wird liegt ja auch am Programmierer ;-)

Mal absehen vom Sinn Deines Beispiels hast Du in der zweiten Variaten ja nur eins, zwei Code Zeilen mehr.
 
Ja, nur findet das Ganze an einer Stelle statt, wo ein String auf mehrere Muster untersucht und je nach Muster verschiedenes mit ihm angestellt werden soll in einer if - else if - else if --- else Abfolge. Während ersteres einfach in die Bedingungen der if-Abfragen gepasst hätte, musste ich nun vor dem Konstrukt alle Pattern und Matcher zusammenbasteln, auch wenn zum Beispiel schon das erste greifen würde.

Oder ich müsste jedes Pattern zweimal durchlaufen (einmal als [c]string.matches(...)[/c] und dann noch als Pattern und Matcher), was unelegant und langsam wäre (wobei langsam hier relativ egal ist).

Oder ich würde in einer boolschen Variablen festhalten, ob ich schon Erfolg hatte. Das würde dann auch lang und wenig schön.

Im Moment mache ich das nun so, dass die Pattern außerhalb der Methode als [c]private final static Pattern[/c] definiert sind (wie andere Pattern auch, nur dass diese nicht so teuer wären) und die Matcher vor dem Abfragekonstrukt gebildet werden.

Das ist nicht ideal, aber solange das kein Flaschenhals ist (und das wird es nicht, da das nur einmal zu Beginn einer langen Bearbeitung danach erfolgt), werde ich das wohl so lassen, falls hier nicht jemandem noch eine weitere, gute Möglichkeit einfällt.
 
Ich sehe da keinen grossen Unterschied. Geht es um das erzeugen eines Matcher Objekts?

Grundsätzlich musst Du ja in beiden Fällen die Muster solange durchlaufen bis einens passt.

Wie ähnlich/unterschiedlich sind denn die Muster? Eventuell lassen diese sich ja noch zusammenfassen. Code in Methoden auslagern hilft auch.
Wie man da am besten vorgeht, hängt auch vom konkreten Anwendungsfall ab.
 
Der Unterschied ist, dass ich nicht alle Muster durchlaufen müsste, wenn denn eines der vorigen greift. Aber da es kein zeitkritischer Part ist, macht das nichts.

Code in Methoden auslagern hat irgendwo eine natürliche Grenze. Ich refakturiere den Code immer mal wieder, wenn mir Methoden zu lang, zu komplex erscheinen oder sie zu viele Dinge auf einmal tun. Aber irgendwo ist eine Grenze erreicht, an der eine Flut von Methoden auch nicht gerade einen guten Überblick verschafft.
 
Das hängt wohl davon ab, wie der Matcher intern funktioniert. Wird der Vergleich beim Definieren gemacht und in .matches() nur abgefragt, oder erfolgt er beim .matchers()-Aufruf?
 
Ich glaube mir reden aneinander vorbei.
Geht es Dir darum was effizienter ist: String#matches() oder oder über ein Pattern einen Matcher zu erzeugen?

String#matches() macht letztendlich auch nichts anderes als ein Pattern zu erzeugen und daraus einen Matcher zu generieren.
 
Wenn man mal davon ausgeht, dass bei Verwendung von Matchern das Pattern bereits kompiliert ist, dann bedeutet diese Variante lediglich zwei Zeilen mehr Code pro Suchmuster.

Java:
Matcher matcher = pattern1.matcher("meinText");
if (matcher.matches() {
    ...
    return;
}
//Falls das erste Muster nicht passt, das nächste prüfen
matcher = pattern2.matcher("meinText");
if (matcher.matches() {...

Java:
if ("meinText".matches("patternText1") {
   ...
}
//Falls das erste Muster nicht passt, das nächste prüfen
else if ("meinText".matches("patternText2") {...

Wenn Du genauer beschreibst was Du vorhast, kann man ein paar Vorschläge zur möglichen Umsetzung machen.
 
Ich kann kein return verwenden an dieser Stelle. Deshalb erwähnte ich die Verwendung der boolschen Variablen. Aber ich werde versuchen, den Block in eine Funktion auszulagern. Dann kann ich dort sehr wohl mit return raus und spare mir unnötige Matcher-Bildungen.

Edit: Ich hab es jetzt so gemacht. Danke nochmal, dass du da mein geistiger Sparringspartner warst. 🙂
 
Zuletzt bearbeitet:

Zurück
Oben