Hauptmenü

Untermenü

PHP/MySQL - Reguläre Ausdrücke - Gierig und ungierig

1. Die Abschnitte

2. Greedy und ungreedy

... sind die korrekten englischen Bezeichnungen für ein Verhalten von Regulären Ausdrücken, dass ich hier einfach mal wortwörtlich übersetzt habe. Wobei sich ungierig ziemlich komisch anhört. Was soll's. Wir haben ja auch so schöne Kreationen wie unabsteigbar oder unkaputtbar.

3. Greedy

Um was geht es denn nun? "Greedy", also "gierig", bedeutet, dass wenn man nach einem regulären Ausdruck sucht, alles gekrallt wird, was nicht niet- und nagelfest ist, solange es in das Muster passt. Greifen wir mal auf das Beispiel aus dem letzten Abschnitt "Klammern" zurück. Da haben wir schön jeden einzelnen Link erfasst. Aber warum? Weil sie alle in verschiedenen Zeilen standen!

Ein feiner Unterschied

Schaut euch mal an, was bei folgendem Beispiel passiert. Das mit dem <a name="..."> habe ich nur aus Platzgründen gemacht.


<?php
  $result '<a name="bla">bla</a> oder <a name="blubb">blubb</a> 
               oder <a name="laber">laber</a>
                und noch etliche weitere';
  preg_match_all ("|<a[^>]*>.+\w</a>|i",$result$links);
  print_r($links);
?>

Da bekommt ihr folgendes Ergebnis:


Array
(
  [0] => Array
    (
      [0] => <a name="bla">bla</aoder <a name="blubb">blubb</a>
      [1] => <a name="laber">laber</a>
    )
)

Und dieses Verhalten nennt man gierig. Das kann man wunderbar daran erkennen, dass der erste Treffer zwei Links enthält. Das liegt daran, dass alle preg-Varianten nach einem Zeilenumbruch eine Pause einlegen und dann von vorne anfangen. Wenn man nun zusätzlich mit dem Modifier s arbeitet, so wird die komplette Zeichenkette als Einheit genommen und man erhält nur noch einen Treffer mit drei Links. Probiert es mal aus.

Tipp

Spielt mal ein wenig mit den Modifiern s und m sowie unterschiedlichen Klammern und PREG_SET_ORDER. Dann wird euch dieses Verhalten genauer vor Augen gehalten.


<?php
  preg_match_all ("|<a[^>]*>.+\w</a>|si",$result$links);
  preg_match_all ("|<a[^>]*>(.+\w)</a>|mi",$result$links);
  preg_match_all ("|(<a[^>]*>)(.+\w)(</a>)|si",$result$links,
                                          PREG_SET_ORDER);
?>

4. Ungreedy

Um diesen verhalten zu unterbinden, muss man einfach nur den Modifier U setzen. Und bitte groß schreiben! Ungreedy oder ungierig bedeutet einfach gesagt, dass bei jedem Treffer neu angefangen wird. Damit wird jeder Link separat erfasst, auch wenn man mit dem Modifier s arbeitet. So bringt folgender Code


<?php
  preg_match_all ("|<a[^>]*>(.+\w)</a>|Usi",
                  $result$linksPREG_SET_ORDER);
?>

dieses Ergebnis:


Array
(
  [0] => Array
    (
      [0] => <a name="bla">bla</a>
      [1] => bla
    )

  [1] => Array
    (
      [0] => <a name="blubb">blubb</a>
      [1] => blubb
    )

  [2] => Array
    (
      [0] => <a name="laber">laber</a>
      [1] => laber
    )
)


zurück zum vorherigen Abschnitt weiter zum nächsten Abschnitt