REGEX - ist Modifier U hier wirklich richtig?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • REGEX - ist Modifier U hier wirklich richtig?

    Hallo
    folgender Code soll die Maße eines *.jpg auf 100x100 skalieren(*)
    Vor u. nach dem IMG steht Text der auch Anführungszeichen, Sonderz. usw. enthalten kann.
    PHP-Code:
    $eingabe 'Text "<em>blabla</em>" vorm Bild <br /><img src="bild.jpg" width="320" height="240" /><br />und mehr "<em>blabla</em>".';
    $pattern '#width="(.*)" height="(.*)"#U'// (s unten **)
    $replace 'width="100" height="100"';        // (s unten ***)
    $ausgabe preg_replace($pattern,$replace,$eingabe);
    echo 
    $ausgabe
    Der Code funzte soweit, nur sobald nach dem Bild Text in Anführungszeichen war ging nix mehr, der IMG TAG u. Texte wurden durcheinander geworfen u. vermischt, usw.

    Habe es mit dem ungierig Modifier U versucht - und siehe da: es klappt!
    Doch ich hab das Gefühl das ging zu einfach, da habi doch sicher was anderes falsch gemacht, oder?

    Denn zb. sobald ich $eingabe in Zeilen trenne, also zb. der Teil nach dem Bild extra steht klappts auch so, ohne U :
    PHP-Code:
    $eingabe 'Text "<em>blabla</em>" vorm Bild <br /><img src="bild.jpg" width="320" height="240" /><br />
    und mehr "<em>blabla</em>".'


    Optimal?
    Doch ich denke mal es wäre sicherer wenn man den ganzen IMG TAG im Suchmuster definieren würde damit die Funktion weiß wo wirklich das Ende des Bildes ist und wo der weitere, unantastbare (Quell)Text beginnt.
    Wie könnte sowas dann aussehen, wo, wie gehöre das notiert, ich kenne das nur soweit das
    Code:
    <img[^>]+>
    den gesamten IMG TAG beschreibt...



    *) Das width u. height hier nur skaliert wird ist Absicht, ich weiß das so nicht wirklich ein kleineres Bild entsteht
    **) ...width="(.*)" height="(.*)"# ist deswegen in Unterausdrücken geklammert weil die eigentlich mittels preg_replace_callback
    weiterverarbeitet werden.
    ***) die Reihenfolge v. width u. height ist immer gleich

  • #2
    Kurz und knapp:

    Der U-Modifier ist eine Lösung in dem Sinne, in dem du sie beabsichtigt hast.

    Denn zb. sobald ich $eingabe in Zeilen trenne, also zb. der Teil nach dem Bild extra steht klappts auch so, ohne U
    Sieh dir den s-Modifier an. "." matcht standardmäßig keine Zeilenumbrüche.

    - PHP: Possible modifiers in regex patterns - Manual

    Doch ich denke mal es wäre sicherer wenn man den ganzen IMG TAG im Suchmuster definieren würde damit die Funktion weiß wo wirklich das Ende des Bildes ist und wo der weitere, unantastbare (Quell)Text beginnt.
    Ja, aber Regex sind da „funktional begrenzt“. Was ist etwa, wenn die Attribute width und height vertauscht sind[1]? Eine gute Lösung wäre ein echter Parser wie DOMDocument.

    - PHP: DOMDocument - Manual

    Aber dennoch: Ein (hoffentlich) etwas „passenderer“ regulärer Ausdruck[2]:

    PHP-Code:
    <?php

    $subject 
    '<img
        src="bla.jpg"
        width="100"
        height="200"/>'
    ;

    $pattern '/<img[^>]*width="([^"]*)"[^>]*height="([^"]*)"[^>]*\/?>/s';

    $matches = array();

    preg_match($pattern$subject$matches);

    header('Content-Type: text/plain; charset=UTF-8');

    print_r($matches);

    /*
    Array
    (
        [0] => <img
        src="bla.jpg"
        width="100"
        height="200"/>
        [1] => 100
        [2] => 200
    )
    */
    Doku zu PCRE: PHP: PCRE Patterns - Manual


    1: Auch das ist wahrscheinlich noch mit einem regulären Ausdruck hinzubiegen (wenn der Attributname auch zurückgeliefert wird), aber irgendwann wird es dann albern.

    2: Manche Stern-Quantifiers sollten vielleicht Plus sein.
    Zuletzt geändert von mermshaus; 04.06.2011, 01:47.

    Kommentar


    • #3
      Hallo u. danke für die Antwort

      Der U-Modifier ist eine Lösung in dem Sinne, in dem du sie beabsichtigt hast.
      dh. so falsch war das mal nicht

      Sieh dir den s-Modifier an. "." matcht standardmäßig keine Zeilenumbrüche.
      ja, den kenn ich - nur irgendwie ging das auch nicht. Doch ich test auch weiter mit dem "s"

      kenn ich, danke - doch für einen REGEX Newbie ist ev. der RegExp-Evaluator leichtere Kost?

      Ja, aber Regex sind da „funktional begrenzt“. Was ist etwa, wenn die Attribute width und height vertauscht sind[1]? Eine gute Lösung wäre ein echter Parser wie DOMDocument.
      - PHP: DOMDocument - Manual
      Tja, klingt ok - nur wie gesagt die zwei Attribute stehen immer so, (Quelle ist der TinyMCE Editor und auf den kann ich mich verlassen das er nicht plötzlich was vertauscht)

      Den
      PHP-Code:
      '/<img[^>]*width="([^"]*)"[^>]*height="([^"]*)"[^>]*\/?>/s' 
      habi mal statt meinen RegAusdruck reingetan, aber irgendwie funzt das so nicht (das Bild ist nu weg) ... hmm, werd ich aber weiter testen. Dzt. zeigt es mir dann das:
      Code:
      Text "blabla" vorm Bild
      width="100" height="100"
      und mehr "blabla".
      Tja, dh. ich muß da noch viel lernen um solche Ausdrücke wie den voll zu kapieren ...


      So sieht das jetzt aus:
      PHP-Code:
      $eingabe 'Text "<em>blabla</em>" vorm Bild <br /><img src="bild.jpg" width="320" height="240" /><br />und mehr "<em>blabla</em>".';
      #$pattern = '#width="(.*)" height="(.*)"#'; // NACH-folgender Text in "" zerstört alles
      #$pattern = '#width="(.*)" height="(.*)"#U'; // so gehts ... aber ist das echt DIE Lösung ??
      #$pattern = '#width="(.*)" height="(.*)"#s'; // will auch nicht ...
      $pattern '/<img[^>]*width="([^"]*)"[^>]*height="([^"]*)"[^>]*\/?>/s'// Tip aus php-resource-forum(user mermshaus)
      $replace 'width="100" height="100"';
      $ausgabe preg_replace($pattern,$replace,$eingabe);
      echo 
      $ausgabe


      1: Auch das ist wahrscheinlich noch mit einem regulären Ausdruck hinzubiegen (wenn der Attributname auch zurückgeliefert wird), aber irgendwann wird es dann albern.
      Glaub ich auch - nur da die Attribute eh so bleiben erübrigt sich das erstmal
      Zuletzt geändert von [pezi]; 04.06.2011, 02:50.

      Kommentar


      • #4
        Ja, mein Ausdruck war nicht als Pattern für preg_replace gedacht.

        Ich habe ihn noch verbessert (auch dahingehend) und kommentiert:

        PHP-Code:
        header('Content-Type: text/plain; charset=UTF-8');

        $eingabe 'Text "<em>blabla</em>" vorm Bild <br /><img src="bild.jpg" class="xy" width="320" height="240" /><br />und mehr "<em>blabla</em>".
            Text "<em>blabla</em>" vorm Bild <br /><img src="bild2.jpg" class="xy" width="800" height="600" /><br />und mehr "<em>blabla</em>".'
        ;

        $pattern '!
                     (<img\s[^>]*width=") # Finde [<img]
                                          # + [ein Whitespace-Zeichen]
                                          # + [beliebig viele Zeichen ungleich >]
                                          # + [width="]
                                          # Speichere diesen Teilstring in $1
                                          #   Beispiel: [<img src="bild.jpg" width="]

                     (?:[^"]*)            # Finde [beliebig viele Zeichen ungleich "]
                                          # Verwerfe diesen Teilstring
                                          #   Beispiel: [320]

                     ("\s[^>]*height=")   # Finde ["]
                                          # + [ein Whitespace-Zeichen]
                                          # + [beliebig viele Zeichen ungleich >]
                                          # + [height="]
                                          # Speichere diesen Teilstring in $2
                                          #   Beispiel: [" height="]

                     (?:[^"]*)            # Finde [beliebig viele Zeichen ungleich "]
                                          # Verwerfe diesen Teilstring
                                          #   Beispiel: [240]

                     ("[^>]*/?>)          # Finde ["]
                                          # + [beliebig viele Zeichen ungleich >]
                                          # + [optional ein /]
                                          # + [>]
                                          # Speichere diesen Teilstring in $3
                                          #   Beispiel: [" />]
                    !x'
        ;

        $replace '${1}100${2}100$3';
                                     
        // Konkateniere: [$1] + [100] + [$2] + [100] + [$3]

        $ausgabe preg_replace($pattern,$replace,$eingabe);

        echo 
        $ausgabe
        Aber… Puh, nein, im Ernst: Nimm das höchstens als generelle Erklärungen. Reguläre Ausdrücke eignen sich dazu einfach nicht (besonders gut). Ich spare es mir deshalb auch, die „Vorteile“ gegenüber dem nächsten Pattern aufzuzeigen.

        Mach lieber sowas, wenn du auf Regex setzen willst:

        PHP-Code:
        <?php

        header
        ('Content-Type: text/plain; charset=UTF-8');

        $eingabe 'Text "<em>blabla</em>" vorm Bild <br /><img src="bild.jpg" class="xy" width="320" height="240" /><br />und mehr "<em>blabla</em>".
            Text "<em>blabla</em>" vorm Bild <br /><img src="bild2.jpg" class="xy" width="800" height="600" /><br />und mehr "<em>blabla</em>".'
        ;

        $pattern '!
                     <img              # Finde [<img]
                     \s+               # Finde [mindestens ein Whitespace-Zeichen]

                     src="([^"]*)"     # Finde [src="]
                                       # + [beliebig viele Zeichen ungleich "]
                                       # + ["]
                                       # Speichere Zeichen zwischen " und " in $1

                     [^>]*             # Finde [beliebig viele Zeichen ungleich [>]
                     /?>               # Finde [optional ein /] + [>]
                    !x'
        ;

        $replace '<img src="$1" height="100" width="100" />';

        $ausgabe preg_replace($pattern,$replace,$eingabe);

        echo 
        $ausgabe;

        Kommentar


        • #5
          Hallo,

          warum quälst du dich überhaupt mit Regex rum, wenn es doch viel bessere Möglichkeiten gibt, HTML zu verarbeiten?

          PHP-Code:
          $doc = new DomDocument();
          $eingabe 'Text "<em>blabla</em>" vorm Bild <br /><img src="bild.jpg" width="320" height="240" /><br />und mehr "<em>blabla</em>".';
          $ausgabe "";
          $doc->loadXml("<div>" $eingabe "</div>");
          foreach (
          $doc->getElementsByTagName("img") as $img) {
              
          $img->setAttribute("width"100);
              
          $img->setAttribute("height"100);
          }
          foreach (
          $doc->documentElement->childNodes as $child) {
              
          $ausgabe .= $doc->saveXml($child);
          }
          echo 
          $ausgabe
          Gruß,

          Amica
          Zuletzt geändert von AmicaNoctis; 04.06.2011, 10:23.
          [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
          Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
          Super, danke!
          [/COLOR]

          Kommentar


          • #6
            Zitat von mermshaus Beitrag anzeigen
            Ja, mein Ausdruck war nicht als Pattern für preg_replace gedacht.
            hab ich dann auch bemerkt das es nur zur Infoausgabe war... Ausserdem , eh klar das bild.jpg nicht erscheint wenn ein Text-Header drin ist, naja, altwerd ...

            Nimm das höchstens als generelle Erklärungen. Reguläre Ausdrücke eignen sich dazu einfach nicht (besonders gut).
            ich werd das am WE alles durchackern, es ist echt gut kommentiert, genau die Erklärung die ich brauch um wieder mal REGEX aufzufrischen!

            Danke !

            Kommentar


            • #7
              Zitat von AmicaNoctis Beitrag anzeigen
              Hallo, warum quälst du dich überhaupt mit Regex rum, wenn es doch viel bessere Möglichkeiten gibt, HTML zu verarbeiten?
              PHP-Code:
              $doc = new DomDocument(); 
              Danke auch dir, das funzt natürlich auch gut. Und wurde mir ja auch von mermshaus vorgeschlagen.
              Und wieder was zum lernen - denn damit kenn ich mich noch weniger aus als mit Regex ...

              Eigentlich "quäle" ich mich mehr aus Testzwecken damit, es gäbe für das Problemchen eh noch andere Möglichkeiten - denn Bilder nur im Quelltext zu skalieren ist sowiso eher sinnfrei. Wie gesagt diese Bildmaß Änderungen nahm ich als Anlass zu schauen ob ich das per Regex überhaupt machen könnte.

              Kommentar

              Lädt...
              X