Andreas Vogt: preg_replace ersetzen

Hallo,
brauche Hilfe beim umsetzen von preg_replace() nach preg_replace_callback()

Habe dazu folgende Anweisung:

$message = preg_replace('#\[ url=([^\]]*) \] (.*?) \[ /url \]#smx','$2',$message);

Wer kann helfen?
Gruß Andreas

  1. Tach,

    brauche Hilfe beim umsetzen von preg_replace() nach preg_replace_callback()

    Habe dazu folgende Anweisung:

    $message = preg_replace('#\[ url=([^\]]*) \] (.*?) \[ /url \]#smx','$2',$message);
    

    wo liegt dein Problem?

    mfg
    Woodfighter

    1. Hallo, meinst du warum ich das ändern möchte? Weil ich diese Fehlermeldungen erhalte: 8192: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead

      1. Tach,

        meinst du warum ich das ändern möchte?

        nein, wo das Problem bei der Umsetzung liegt.

        Weil ich diese Fehlermeldungen erhalte: 8192: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead

        Der e-Modifier ist im von dir geposteten Code übrigens nicht enthalten.

        mfg
        Woodfighter

        1. Hallo

          Der e-Modifier ist im von dir geposteten Code übrigens nicht enthalten.

          Ich weiss, bekomme aber trotzdem die Fehlermeldung. Habe es so probiert:

          $message = preg_replace_callback('#\[ url=([^\]]*) \] (.*?) \[ /url \]#smx',
          Function $m{
              return $m[2];
          }, $message);
          

          Hat nicht funktioniert, die Webseite war leer. Lag es daran dass Array 0-basiert ist und ich $m[1] schreiben müsste?

          1. Tach,

            $message = preg_replace_callback('#\[ url=([^\]]*) \] (.*?) \[ /url \]#smx',
            Function $m{
                return $m[2];
            }, $message);
            

            Hat nicht funktioniert, die Webseite war leer.

            Die Fehlermeldung landet dann im Error-Log des Webservers.

            Lag es daran dass Array 0-basiert ist und ich $m[1] schreiben müsste?

            Ja, Arrays sind 0-basiert, aber RegEx-Callbacks auch. Du hast bei der Definition deiner anonymen Funktion allerdings die Klammern um den Parameter vergessen. Das Syntax-Highlighting hier im Forum zeigt diesen Fehler übrigens auch an (roter Hintergrund); falls dein Editor das nicht tut, solltest du dir vielleicht einen anderen besorgen.

            mfg
            Woodfighter

            P.S. PHP ist zwar teilweise[1] case-insensitive, aber üblicher Stil ist, dass Keywords wie function klein geschrieben werden.


            1. http://the-echoplex.net/log/php-case-sensitivity ↩︎

            1. Hallo,

              ...allerdings die Klammern um den Parameter vergessen.

              Danke, das hat funktioniert. Bei einem komplexeren Ausdruck funktioniert es allerdings nicht:

              $message = preg_replace(
              	'/((<a.+\/a>)|(\b'. preg_quote(strtr($word, array('\'' => '&#039;')), '/'). '(?=[^A-Za-z0-9&agrave;-ÖØ-öø-ÿ_\-s]))|(\b'.preg_quote(strtr($word, array('\'' => '&#039;')), '/').'\b))/'. (!empty($modSettings['glossary_none_sensitive']) ? 'i' : '') .'e' ,
              	"'\$2' == '\$1' ? stripslashes('\$1') : '<span class=\"glossary\" title=\"".addslashes($definition)."\">$1</span>'", 
              	$message, 
              	(isset($modSettings['glossary_unique_word']) && $modSettings['glossary_unique_word']==1) ? 1 : -1 
              );
              

              Meine übersetzung ist diese:

              $message = preg_replace_callback(
              	'/((<a.+\/a>)|(\b'. preg_quote(strtr($word, array('\'' => '&#039;')), '/'). '(?=[^A-Za-z0-9&agrave;-ÖØ-öø-ÿ_\-s]))|(\b'.preg_quote(strtr($word, array('\'' => '&#039;')), '/').'\b))/'. (!empty($modSettings['glossary_none_sensitive']) ? 'i' : '') .'e' , 
              	function ($match) {
               		return "'$match[1]' == '$match[0]' ? stripslashes('$match[0]') : '<span class=\"glossary\" title=\"".addslashes($definition)."\">$match[0]</span>'";
              	},
              	$message, 
              	(isset($modSettings['glossary_unique_word']) && $modSettings['glossary_unique_word']==1) ? 1 : -1 
              );
              

              Die Webseite lädt, die einzelnen Inhalte ($message) fehlen. Es ist doch korrekt $2 durch $match[1] zu ersetzen? Habe es auch mit dem Backslach vor $match probiert, gleiches Ergebnis.

              Any Ideas? Gruß Andreas

              1. Tach,

                Es ist doch korrekt $2 durch $match[1] zu ersetzen?

                nein: Arrays sind 0-basiert, aber RegEx-Callbacks auch.

                Habe es auch mit dem Backslach vor $match probiert, gleiches Ergebnis.

                Statt mit irgendwelchen Dingen herumzuprobieren, bietet es sich meist an, sich Debugausgaben der verwendeten Ausdrücke ausgeben zu lassen (z.B. mit var_dump). Dein zitierter Code sieht übrigens sehr undurchsichtig aus, so undurchsichtig, dass ich eingie Zeit gebraucht habe, zu sehen, dass z.B. stripslashes und der Ternary Operator in deiner Variante innerhalb eines Strings stehen und deshalb definitiv nicht ausgeführt werden.

                mfg
                Woodfighter

                1. Hallo, danke für deine Mühe. Habe den Codeteil jetzt doch herausgenommen, so wichtig war es jetzt auch nicht dass ich noch mehr Zeit investiere. Auf jedenfall weiss ich jetzt dass ich eigentlich gar nicht so viel weiss. Ist ja auch was.

                  Gruß Andreas

              2. Es ist doch korrekt $2 durch $match[1] zu ersetzen? Habe es auch mit dem Backslach vor $match probiert, gleiches Ergebnis.

                Bezieht sich auf den Index der capture group. $1 bzw $m[1] für das was mit erstem geklammertem Teilmuster übereinstimmt usw.

                Any Ideas?

                Probier mal als callback etwas in der Art.

                function ($m) { return $m[2] == $m[1] ? stripslashes($m[1]) : '<span class="glossary" title="'.addslashes($definition).'">'.$m[1].'</span>';
                

                }

                Habs nicht getestet.

                Finde auch, dass dein Code sehr unübersichtlich ist. Man muss es sich doch nicht so schwer machne.

                LG, Robert

  2. Hallo,
    brauche Hilfe beim umsetzen von preg_replace() nach preg_replace_callback()

    Hallo Andreas,

    für was denn ein callback? Da sollte doch preg_replace ausreichen.

    $message = preg_replace('~\[url=[^\]]*\](.*?)\[/url\]~s', "$1", $message);
    

    Mit nur einer capture group und ohne multiline flag, da ja gar kein ^ für Anfang oder $ vorkommt.

    Falls du doch ein callback benötigen solltest, es wurde ja schon erwähnt, dass die Klammern um den Parameter fehlen. Weiters ist für die Verwendung anonymer Funktionen mindestens PHP 5.3 nötig.

    LG, Robert