RegEXP, Wiki und Tabellen

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

  • RegEXP, Wiki und Tabellen

    Ich versuche gerade mein eigenes kleines Wiki in PHP zu schreiben. Die Beispiele für reguläre Ausdrücke sind super, daher hatte ich mich entschieden RegExp auch in meinem Projekt zu verwenden.
    Jetzt hänge ich hier an dem Problem Tabellen zu parsen. Die Syntax hat zwei Varianten und sie sehen wie folgt aus:

    Variante 1:

    {| border="1" cellspacing="5px" cellpadding="0px"
    |Zelle 1
    |Zelle 2
    |-
    |Zelle 3
    |Zelle 4
    |}
    Variante 2:

    {| border="1" cellspacing="5px" cellpadding="0px"
    |Alpha || Beta || Gamma
    |----
    |Delta || Epsilon || Zeta
    |}
    Die Parameter in den Varianten 1 und Variante 2 (z.B. 'color="#FF0000"') sind optinal, aber ich will sie für die Gestaltung der Tabellen auswerten.
    Mein Problem ist, wie erstelle ich den regulären Ausdruck am besten und wie schaffe ich es, dass ich die 2. Variante korrekt erkenne?
    Meine Lösung basiert auf einem Lösungsvorschlag aus dem Thread Wiki und Listen von Luke und bisher habe ich ihn nicht korrekt anpassen können.

    PHP-Code:
    function find_table($string)
    {
        
    $table_string preg_replace("/\n(\{\|(-\n|\|.*)\|\})\n/Use""<table>\n\t<tr>\$this->do_table('\\2') \t</tr></table>\n"$string);
          return 
    table_string;
    }

    function 
    do_table($string)
    {
          
    $string preg_replace("/\|([^\n]*)\n/""\\1"$string);
            
    $string preg_replace("-\n","\t</tr>\n\t<tr>\n",$string);
            if (
    $string== "\t</tr>\n\t<tr>\n")
                  return 
    $string;
          return 
    "\n<td>".$string."</td>".$s;

    Ich wäre sehr dankbar dafür, wenn mir jemand einen Tip geben könnte oder helfen würde.
    Vielen Dank schon mal im Voraus.

    P.S.: Eine komplette Übersicht über die Wikisyntax kann man unter Wikisyntax finden.
    Zuletzt geändert von Norad; 16.11.2004, 11:44.

  • #2
    Ich hab jetzt ein wenig rumgebastelt und den folgenden Ansatz gebastelt. Leider funktioniert er auch nicht so, wie er soll. Ich finde den Fehler einfach nicht.

    PHP-Code:
    <?php
        $master
    ="\n{|\n| heise\n-\n| \n|}\n";

        function 
    do_tr($string)
        {
            return 
    preg_replace("!\n-\n!","\n</tr>\n<tr>\n",$string);
        }

        function 
    do_td($string)
        {
            return 
    preg_replace("!\n\|\s(.*?)\n!","\n<td> \\\\1 </td>\n",$string);
        }

        function 
    do_table($string)
        {
            return 
    preg_replace("!\\{\\|\n(.*?)\\|\\}\n!","\n<table><tr>\n \\\\1 \n</tr></table>",$string);
        }
        
        echo 
    do_td(do_tr($master));
        echo 
    "<br>".do_td(do_tr(do_table($master)));
    ?>
    Zuletzt geändert von Norad; 16.11.2004, 11:42.

    Kommentar


    • #3
      So ich habe ein wenig weiter experimentiert:

      PHP-Code:
      <?php
          $master
      ="{|
      | heise
      | fujitsu
      -

      | Einfach nur einTest
      |}
      "
      ;

          function 
      do_tr($string)
          {
              return 
      preg_replace("!\n-\n!is","\n\t</tr>\n\t<tr>\n",$string);
          }

          function 
      do_td($string)
          {
              return 
      preg_replace("!\n\|([^\n]*?)!","\n\t\t<td>\n\t\t\t\\1\n\t\t</td>\n",$string);
          }

          function 
      do_table($string)
          {
              return 
      preg_replace("!\{\|\n(.*?)\|\}\n!is","\n<table>\n\t<tr>\n\\1\n\t</tr>\n</table>\n",$string);
          }

          function 
      do_test($string,$test)
          {
              return 
      preg_replace($test," >>> War erfolgreich <<< "$string);
          }    
          
          echo 
      "<br>".do_tr(do_td(do_table($master)));
      ?>
      Aber ich bekomme davon folgende Ausgabe:

      <br>
      <table>
      <tr>
      <td>

      </td>
      heise
      <td>

      </td>
      fujitsu
      </tr>
      <tr>

      <td>

      </td>

      <td>

      </td>
      Einfach nur ein Test

      </tr>
      </table>
      Warum langen die Texte hinter den TD-Tags, wenn sie bei der Backreference dazwischen stehen?

      Kommentar


      • #4
        PHP-Code:
            $master="{|
        | heise
        | fujitsu
        -
        |
        | Einfach nur einTest
        |}
        "
        ;

            function 
        do_td($string)
            {
                return 
        preg_replace('#\|(.*)#','<td>\1</td>',$string);
            }

            function 
        do_tr($string)
            {
                return 
        preg_replace('#^-#m''</tr><tr>',$string);
            }

            function 
        do_table($string)
            {
                return 
        preg_replace('#\{\|(.+)\|\}#Uis','<table><tr>\1</tr></table>',$string);
            }

            function 
        do_test($string,$test)
            {
                return 
        preg_replace($test," >>> War erfolgreich <<< "$string);
            }

            echo 
        do_td(do_tr(do_table($master))); 
        so gehts bei mir
        ps: forum frisst \
        Die Zeit hat ihre Kinder längst gefressen

        Kommentar


        • #5
          PHP-Code:
              $master='
          {| border="1" cellspacing="5px" cellpadding="0px"
          | heise
          | fujitsu
          -

          | Einfach nur einTest
          |}
          '
          ;

            
          $master2 '
          {| style="background:#DDD; color:#000; border:solid; "
          |Alpha || Beta || Gamma
          |----
          |Delta || Epsilon || Zeta
          |}
          '
          ;

            
          $regexps = array(
              
          '#\{\|(.*)\r\n(.*)\|\}#Uis',
              
          '#-|\|----#m',
              
          '#\|(.*)#',
              
          '#\|\|#'
            
          );

            
          $replaces = array(
              
          '<table\1><tr>\2</tr></table>',
              
          '</tr><tr>',
              
          '<td>\1</td>',
              
          '</td><td>'
            
          );

            echo 
          preg_replace($regexps$replaces$master);
            echo 
          preg_replace($regexps$replaces$master2); 
          so scheint es für beide versionen zu funktionieren ... schau mal ...

          wie immer: beitrag zitieren, um an den code zu kommen.
          Die Zeit hat ihre Kinder längst gefressen

          Kommentar


          • #6
            Vielen Dank derHund.
            Ich habs mal getestet. Bei mir kam folgendes Ergebnis heraus.

            {<td> border="1" cellspacing="5px" cellpadding="0px"</td>
            <td> heise</td>
            <td> fujitsu</td>
            </tr><tr>
            <td></td>
            <td> Einfach nur einTest</td>
            <td>}</td>

            {<td> style="background:#DDD; color:#000; border:solid; "</td>
            <td>Alpha </td><td> Beta </td><td> Gamma</td>
            </tr><tr>
            <td>Delta </td><td> Epsilon </td><td> Zeta</td>

            <td>}</td>
            Danke für den Tip mit Zitat. Das Listing habe ich über Zitat herausgeholt und es hatte die Form:

            PHP-Code:
            <?php
            $master
            ='
            {| border="1" cellspacing="5px" cellpadding="0px"
            | heise
            | fujitsu
            -
            |
            | Einfach nur einTest
            |}
            '
            ;

              
            $master2 '
            {| style="background:#DDD; color:#000; border:solid; "
            |Alpha || Beta || Gamma
            |----
            |Delta || Epsilon || Zeta
            |}
            '
            ;

              
            $regexps = array(
                
            '#\{\|(.*)\r\n(.*)\|\}#Uis',
                
            '#-|\|----#m',
                
            '#\|(.*)#',
                
            '#\|\|#'
              
            );

              
            $replaces = array(
                
            '<table\1><tr>\2</tr></table>',
                
            '</tr><tr>',
                
            '<td>\1</td>',
                
            '</td><td>'
              
            );

              echo 
            preg_replace($regexps$replaces$master);
              echo 
            preg_replace($regexps$replaces$master2);
              
            ?>
            Ich hab noch einen Effekt bemerkt. Er ersetzt mir beim Eingabe String " durch \" (z.B. color="#FF0000" zu color=\"FF0000\") und das lässt sich auch nicht rückgängig machen. Wie kann ich das verhindern?
            Zuletzt geändert von Norad; 16.11.2004, 17:23.

            Kommentar


            • #7
              und das lässt sich auch nicht rückgängig machen. Wie kann ich das verhindern?
              such mal nach 'magic quotes' ... dazu gibt es eine menge fragen, antworten, codeschnipsel ...
              Die Zeit hat ihre Kinder längst gefressen

              Kommentar


              • #8
                Vielen dank für die Infos derHund

                Ich habe alle Regeln unter PCRE Evaluator getestet und wie erwartet haben sie funktioniert. Aber selbst bei einzeltests auf in einzelnen Skripts z.B.

                PHP-Code:
                <?php
                $master
                ='
                {| border="1" cellspacing="5px" cellpadding="0px"
                | heise
                | fujitsu
                -
                |
                | Einfach nur einTest
                |}
                '
                ;

                  
                $master2 '
                {| style="background:#DDD; color:#000; border:solid; "
                |Alpha || Beta || Gamma
                |----
                |Delta || Epsilon || Zeta
                |}
                '
                ;

                  
                $regexps =
                    
                '/\{\|(.*)\r\n(.*)\|\}/isU';

                  
                $replaces =
                    
                '<table\1><tr>\2</tr></table>';

                  echo 
                preg_replace($regexps$replaces$master);
                  echo 
                preg_replace($regexps$replaces$master2);
                  
                ?>
                hat es nicht geklappt. Wo liegt da der Fehler? Wie geht preg_replace bei Übergabe zweier Arrays vor? Matcht es bei erfolgreicher Anwendung von Regel "0" auch Ersetzung "0"? Wenn ja müssen dann beide Arrays gleiche Länge habe?

                Kommentar


                • #9
                  Aber selbst bei einzeltests auf in einzelnen Skripts z.B. [...] hat es nicht geklappt.
                  hmm ... was ging denn nicht? zumindest die table sollte ersetzt werden ...
                  Wo liegt da der Fehler?

                  Wie geht preg_replace bei Übergabe zweier Arrays vor?
                  bei gleicher anzahl von elementen wird immer das entsprechende genommen 0 = 0, 1 = 1 ... schau mal manual, bei unterschiedlicher anzahl weiß ichs nicht.

                  aber wie gesagt, bei mir hats funktioniert. notfalls kannst du mal für beide tabellenarten einzelne regeln aufstellen ... oder mal das beispiel posten, das nicht geht.
                  Die Zeit hat ihre Kinder längst gefressen

                  Kommentar


                  • #10
                    Bei Ausführung des oben angegebenen Skripts bekomme ich immer diese Ausgabe:

                    {| border="1" cellspacing="5px" cellpadding="0px" | heise | fujitsu - | | Einfach nur einTest |} {| style="background:#DDD; color:#000; border:solid; " |Alpha || Beta || Gamma |---- |Delta || Epsilon || Zeta |}
                    Der HTML-Quelltext war dabei:

                    {| border="1" cellspacing="5px" cellpadding="0px"
                    | heise
                    | fujitsu
                    -
                    |
                    | Einfach nur einTest
                    |}

                    {| style="background:#DDD; color:#000; border:solid; "
                    |Alpha || Beta || Gamma
                    |----
                    |Delta || Epsilon || Zeta
                    |}
                    Es sieht so aus, als würde die Regel nicht auf die Eingabe matchen. Die Regexp funktioniert aber beim PCRE Evaluator.

                    Kommentar


                    • #11
                      Die Regexp funktioniert aber beim PCRE Evaluator.
                      lustigerweise funktioniert das ersetzen einwandfrei, wenn ich es teste ... habe deinen code (den, wo nur table ersetzt wird) kopiert und getestet ... geht perfekt ....
                      Die Zeit hat ihre Kinder längst gefressen

                      Kommentar


                      • #12
                        Kann das an meiner PHP Version liegen? Meine aktuelle Version ist 5.0.2. Bei mir gehts eindeutig nicht.

                        Unter phpinfo() habe ich folgenden Eintrag für PCRE:

                        pcre
                        PCRE (Perl Compatible Regular Expressions) Support enabled
                        PCRE Library Version 4.5 01-December-2003

                        Kommentar


                        • #13
                          Kann das an meiner PHP Version liegen? Meine aktuelle Version ist 5.0.2. Bei mir gehts eindeutig nicht.
                          ich hab 4.3, also bezogen auf die pcre ....

                          das einzige, was mir noch einfiele, und was mich schon gestern gewundert hat, daß es so überhaupt funktioniert, wäre:

                          der regexp
                          Code:
                          '/\{\|(.*)\r\n(.*)\|\}/isU'
                          steht ja in ' (single quotes), findet aber anscheinend trotzdem den zeilenumbruch (eigentlich sollte er nur die zeichen \r\n finden, aber nicht den umbruch). setz den mal in " (double quotes), eventuell gehts dann .... bzw. eigentlich dürfte es nur dann gehen ... sonst weiß ich auch nix.

                          sonst mußt du dir halt eine andere syntax suchen, mit der es geht ... da sollte es noch möglichkeiten geben ....

                          sachen gibts ...
                          Die Zeit hat ihre Kinder längst gefressen

                          Kommentar


                          • #14
                            Hmm dann liegts an der PCRE Engine in PHP 5.0.2, dass dieser Ausdruck nicht richtig ausgewertet wird.
                            Ich hab jetzt auch Deine Änderungen eingepflegt, aber das Ergebnis blieb das selbe.
                            Weisst Du, wo man Anfragen, die ein möglichen Problem von PHP angehen, stellen kann?

                            Kommentar


                            • #15
                              Weisst Du, wo man Anfragen, die ein möglichen Problem von PHP angehen, stellen kann?
                              keine ahnung.

                              vielleicht findest du in den change-logs der pcre irgendwas, aber frag mich nicht, wo du die findest ...

                              versuch lieber, einen anderen syntax zu finden ... oder geh den jetzigen schritt für schritt durch, bis du den punkt findest, wo es 'aushakt' - wenns dir nicht zu aufwändig ist. dann wissen wir wenigstens, wo dran es liegt.

                              ich schau nachher auch nochmal, atm gehts nicht ...
                              Die Zeit hat ihre Kinder längst gefressen

                              Kommentar

                              Lädt...
                              X