mixmastertobsi: regular expression Problem - alles außer bestimmtest Wort

Hallo,

wie schreibe ich einen regulären Ausdruck, dass alles vorkommen darf, bis auf ein bestimmtes WOrt.

Ich habe ein einfaches Beispiel gemacht

$test= "<p>testtest</p><b>test2test2</b><p>test3</p>";
$test= preg_replace("/<p>(?!<\/p>)..*<\/p>/i","",$test);

Aktuell löscht das SKript alles, weil es vom ersten bis zum letzten P-Tag geht. ich möchte aber, dass sobald der P-Tag geschlossen wird, die Suche beendet ist.

Im Ergebnisse sollte also beim dem String noch "<b>test2test2</b>" stehen bleiben.

  1. Tach!

    Aktuell löscht das SKript alles, weil es vom ersten bis zum letzten P-Tag geht. ich möchte aber, dass sobald der P-Tag geschlossen wird, die Suche beendet ist.

    Regex sind gierig (greedy). Sie nehmen alles bis zum letzten passenden Muster. Man kann die Gierigkeit (greediness) deaktivieren. Unter dem Stichwort findest du die passende Syntax im Regex-Tutorial deiner Wahl.

    dedlfix.

  2. Servus mixmastertobsi,

    $test= "<p>testtest</p><b>test2test2</b><p>test3</p>";
    $test= preg_replace("/<p>(?!<\/p>)..*<\/p>/i","",$test);
    

    Im Ergebnisse sollte also beim dem String noch "<b>test2test2</b>" stehen bleiben.

    Bis jetzt ist dein Regex noch gierig. "/<p>(?!</p>)..*</p>/iU" tut in deinem Beispiel, was du willst.

    Siehe: http://php.net/manual/de/reference.pcre.pattern.modifiers.php -> U (PCRE_UNGREEDY)

    ciao

    --
    "Sir, we are surrounded" - "Excellent, we can attack in any direction!"
    1. Ohne U sind Wiederholungsoperatoren per Default greedy, mit der U Option werden sie per Default lazy. Es gibt darüber hinaus die Möglichkeit, dem Wiederholungsoperator ein ? nachzustellen, um pro Operator zwischen greedy und lazy umzuschalten. Ich habe das in meinem Vorschlag unten mal gemacht. Muss man nicht.

      An Stelle von * gibt es noch das +, um mindestens ein Match zu haben. Du kannst ..* durch .+ ersetzen. Du kannst aber auch einfach .* schreiben, weil <p></p> dank der negativen Assertion sowieso nicht gematcht wird.

      Und das / brauchst Du nicht zu escapen, wenn Du einen anderen Regex-Delimiter nimmst. Z.B.:

      @<p>(?!</p>).*?</p>@i
      

      Ist es eigentlich wirklich deine Absicht, <p></p> nicht zu matchen?

      Und ich frage mich noch, ob Du die g Option hinzufügen musst (global), um mehr als einen Paragraphen zu replacen.

      Hier kannst Du übrigens spielen.

      Rolf