Ankündigung

Einklappen
Keine Ankündigung bisher.

reg_exp um object method aus template auszulesen

Einklappen

Neue Werbung 2019

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

  • reg_exp um object method aus template auszulesen

    Guten Abend,

    ich möchte aus einem String heraus den Aufruf einer Object Method ansteuern. Dabei bekomme ich mit dem unten stehenden RegExp schon annähernd das korrekte Ergebnis.

    PHP-Code:
    $regexp '/\{\$(\w+){1}(?:(?:\.|->)(\w+)\(\))*\}/is';
    $text '<p>{$obj->test()->foobar()}</p>';

    function 
    callback($text){
        
    var_dump($text);
    }

    echo 
    preg_replace_callback($regexp'callback'$text); 
    Ausgabe des var_dump's:
    Code:
    array(3) { 
     [0]=> string(24) "{$obj->test()->foobar()}" 
     [1]=> string(3) "obj" 
     [2]=> string(6) "foobar" 
    }
    Was ich gerne als Ausgabe des var_dump's hätte:
    Code:
    array(3) { 
     [0]=> string(24) "{$obj->test()->foobar()}" 
     [1]=> string(3) "obj" 
     [2]=> string(3) "test" 
     [3]=> string(6) "foobar" 
    }
    Wie muss ich die RegExp anpassen, bzw. welches ist das richtige Stichwort mit dem ich beschäftigen sollte um dieses Ergebnis zu erzielen?

  • #2
    Das wird so nicht funktionieren. Jedenfalls nicht mit dem Wiederholungsoperator. Du kannst bspw. 10 identische, optionale Pattern ins den Ausdruck bauen, bist damit aber immer auf die statische Anzahl festgelegt und wirst auch immer für alle ein Matching bekommen. Im Zweifel ein leeres.

    Kommentar


    • #3
      Könnte man das ganze vllt. rekursiv lösen?

      Kommentar


      • #4
        matching ja, aber capturing eben nicht, imho. Warum muss es denn unbedingt ein Ausdruck sein? Könnte man ja auch bspw. durch Rekursion in PHP lösen. Oder mit explode o.ä.

        Kommentar


        • #5
          Wenns Dir nur um das Ergebnis geht, würde es so meine ich hinhauen, wie Du es Dir vorstellst:
          PHP-Code:
          $sText '<p>{$obj->test()->foobar()}</p>'
          $aCallPath = array();

          preg_replace_callback(
                  
          '/(?<=\$|\>)([^\-\<\>\$\{\}\(\)]+)/is',
                  function( 
          $sFetch ) use ( &$aCallPath ) {
                      
          $aCallPath[] = $sFetch[0];
                  },
                  
          $sText
              
          );

          var_dump$aCallPath ); 
          oder alternativ über preg_match_all ( warum muß es preg_replace_callback sein? ):
          PHP-Code:
          $sText '<p>{$obj->test()->foobar()}</p>'
          preg_match_all'/(?<=\$|\>)([^\-\<\>\$\{\}\(\)]+)/is'$sText$aMatches );
          var_dump$aMatches[0] ); 
          Beides erzeugt diese Ausgabe:
          Code:
          array(3) {
            [0]=>
            string(3) "obj"
            [1]=>
            string(4) "test"
            [2]=>
            string(6) "foobar"
          }

          Kommentar


          • #6
            ( warum muß es preg_replace_callback sein? )
            Weil der modifier /e bei preg_match() seit 5.5 deprecated ist.

            Kommentar


            • #7
              Öhm... Ja gut... Dennoch reicht doch für seinen Zweck das preg_match_all(), oder nicht

              Kommentar


              • #8
                Naja, aber auch nur, weil das so ein spezieller Fall ist. $ nicht mitmatchen, leere Methodenparameter etc.

                Kommentar


                • #9
                  Ach guck mal... Methodenparameter habe ich gar nicht berücksichtigt.

                  Kommentar


                  • #10
                    Im Prinzip ist das genau das @Arne Drews was ich haben wollte, aber wie nikosch richtig festgestellt hat sollen dann zukünftig natürlich auch Parameter mit übergeben werden können.

                    Deswegen werde ich dann doch alle {$ ... } matchen und die dann entsprechend exploden.

                    Weitere Ideen sind gern gesehn, deswegen schließ ich den Thread erstmal noch nicht.

                    Danke

                    Kommentar


                    • #11
                      [...]aber wie nikosch richtig festgestellt hat sollen dann zukünftig natürlich auch Parameter mit übergeben werden können.
                      PHP-Code:
                      $sText '<p>{$obj->test("string", int)->foobar(bool, 3.5)}</p>'
                      preg_match_all'/(?<=\$|\>)([^\-\<\>\$\{\}\(\)]+(\([^\(\)]*\))?)/is'$sText$aMatches );
                      var_dump$aMatches[0] ); 
                      Code:
                      array(3) {
                        [0]=>
                        string(3) "obj"
                        [1]=>
                        string(19) "test("string", int)"
                        [2]=>
                        string(17) "foobar(bool, 3.5)"
                      }

                      Kommentar


                      • #12
                        $bool kann er halt z.B. nicht.

                        Kommentar


                        • #13
                          Das ist wahr... Dann bleibt fast nur noch, das mit explode etc. zu zerlegen.

                          Kommentar


                          • #14
                            Sehr nice....bedenken müsste man dann evtl. auch noch Variablen die mit übergeben werden könnten. Das kann man ja dann aber auch nach dem man das $aMatch Stück für Stück durchgeht und die Parameter exploded rekursiv ggf durchlaufen lassen.

                            Wie sieht das dann eigentlich mit der Geschwindigkeit aus? Ist ein komplizierterer Pattern langsamer als ein einfacher mit ergänzenden z.B. explode Methoden, die dann das gleiche Ergebnis liefert.

                            Kommentar


                            • #15
                              Probiers aus, fertig.

                              Kommentar

                              Lädt...
                              X