Java ist auch eine Insel

Dienstag, März 11, 2008

Inselupdate: Quantifizierer mit Wiederholungen, nicht gierige Operatoren

Wiederholungen

Neben Quantifizierern ? (einmal oder keinmal), * (keinmal oder beliebig oft) und + (einmal oder beliebig oft), gibt es drei weitere Quantifizierer, die es erlauben, die Anzahl eines Vorkommens genauer zu beschreiben.

  • X{n}. X muss genau n-mal vorkommen
  • X{n,}. X kommt mindestens n-mal vor
  • X{n,m}. X kommt mindestens n aber maximal m-mal vor

Beispiel   Eine E-Mail Adresse endet mit einem Domain-Namen, der 2 oder 3 Zeichen lang ist.

static Pattern p = Pattern.compile( "[\\w|-]+@\\w[\\w|-]*\\.[a-z]{2,3}" );

 

Gierige und nicht gierige Operatoren

Die drei Operatoren ?, * und + haben die Eigenschaft, die längste mögliche Zeichenfolge abzudecken – das nennt sich gierig (engl. greedy). Deutlich wird diese Eigenschaft, bei dem Versuch, in einem HTML-Strings alle fett gesetzten Teile zu finden. Gesucht ist also ein Ausdruck, der im String

String string = "Echt <b>fett</b>. <b>Cool</b>!";

die Teilfolgen <b>fett</b> und <b>Cool</b> erkennt. Der erste Versuch für ein Programm:

Pattern pattern = Pattern.compile( "<b>.*</b>" );

Matcher matcher = pattern.matcher( string );

while ( matcher.find() )

System.out.println( matcher.group() );

Nun ist die Ausgabe aber <b>fett</b>. <b>Cool</b>! Das verwundert nicht, denn mit dem Wissen, dass * gierig ist, passt <b>.*</b> auf die Zeichenkette vom ersten <b> bis zum letzten </b>.

Die Lösung ist der Einsatz eines nicht gierigen Operators (auch „genügsam“, „zurückhaltend“, „non-greedy“, „reluctant“ genannt). Dieser Operator bekommt einfach hinter dem Qualifizierer ein Fragezeichen gestellt.

Mit diesem nicht-gierigen Operator lösen wir einfach das Fettproblem:

Pattern pattern = Pattern.compile( "<b>.*?</b>" );

Matcher matcher = pattern.matcher( "Echt <b>fett</b>. <b>Cool</b>!" );

while ( matcher.find() )

  System.out.println( matcher.group() );

Die Ausgabe ist:

<b>fett</b>

<b>Cool</b>

Labels: ,

AddThis Social Bookmark Button