Gustav Gans: Gefundene AUsdrücke in einem Text markieren

Hi!

Folgendes möchte ich realisieren:

Auf einer html Seite befindet sich ein fix vorgegebener Text. Darunter ein Formular mit einem Eingabefeld und einem Absendebutton.

Wenn man nun in das Eingabefeld irgend einen Wortteil eingibt und auf Absenden klickt, soll auf der nun geladenen Seite 2 der Text von Seite 1 erscheinen, und zwar so, daß alle Stellen im Text, die der Eingabe entsprechen, farblich hervorgehoben sind.

Also daß ich mittels php in den Text überall dort ein <span style="..."> vor und ein </span> nach den entsprechenden Stellen einbaue.

Da ich php-Anfänger bin, bitte ich um Hilfe:

Mit welchen Funktionen muß ich mich beschäftigen?

Mich interessiert sowohl ein Weg mit Suchen und Ersetzen, als auch eine Möglichkeit mit regulären Ausdrücken.

Könnt Ihr mir bitte einen UNGEFÄHREN Aufbau / php-Ablauf aufzeigen, damit ich nicht völlig planlos beginne?

Dank!

Gustav Gans

  1. Mich interessiert sowohl ein Weg mit Suchen und Ersetzen, als auch eine Möglichkeit mit regulären Ausdrücken.

    Reguläre Ausdrücke brauchst du nur, wenn der Kontext, in dem das Suchwort vorkommt, eine Rolle spielt und beachtet werden muss.
    Trotzdem ist preg_replace angebracht, damit kannst du komfortabel nach einem String suchen und ihn in <span> und </span> einfassen. Mit $0, $1 usw. kannst du nämlich im Ersatz-String auf die Treffer und Teiltreffer, d.h. das gefundene Wort zugreifen und es wieder einsetzen. Und mit dem i-Flag kannst du unabhängig von Groß- und Kleinschreibung suchen.

    preg_replace('~(Wort)~i', '<span class="found">$1</span>')

    Das kannst du natürlich jetzt noch verbessern, z.B. indem "Wort" freistehend sein muss, sonst wäre auch "verantworten" ein Treffer (verant<span class="found">wort</span>en). Dazu kannst du dir mal \W ansehen, das du vor und nach die Klammer stellen könntest.

    Schwieriger wird es, wenn du HTML-Formatierungen hast und der Text nicht in HTML-Tags gefunden werden soll, siehe: http://php-faq.de/q-regexp-ersetzen.html

    Mathias

  2. Hallo

    Mit welchen Funktionen muß ich mich beschäftigen?

    du müsstes als erstes versuchen den Text einzulesen, z.b.
    $string1 = fread($fp, filesize($filename));

    Dann mit Hilfe deines Suchwortes und regulären Ausdrücken suchen:
    preg_match_all()
    oder gleich ale Fundstellen mit
    $neu = preg_replace("#DEIN_SUCHWORT#","<span>...</span>",$ergebnis);
    ersetzen.

    viele Grüße
    hawk

    1. Hi!

      Dann mit Hilfe deines Suchwortes und regulären Ausdrücken suchen:
      preg_match_all()

      Oje, ich scheiteres schon DARAN. :-(

      Beispiel: In dem Text "4U2 ist ein oft verwendetes Passwort. 2t9 aber auch. Wie sich das mit 1+2 verhält, weiß ich nicht." sollen alle Teile, bestehend aus Ziffer-Nichtziffer-Ziffer extrahiert UND ausgegeben werden.

      <?php  
       $text="4U2 ist ein oft verwendetes Passwort. 2t9 aber auch. Wie sich das mit 1+2 verhält, weiß ich nicht.";  
       preg_match_all("#\d\D\d#",$text,$treffer);  
      ?>
      

      Aber wie schaffe ich jetzt die Ausgabe der gefundenen Teile?

      Meine erste Lösung war:

      foreach($treffer as $wert)  
       {  
        echo $wert."\n";  
       }
      

      Dann kommt aber einfach nur das Wort "Array" als Ausgabe.

      Mit Hilfe des php-Handbuches habe ich dann Folgendes versucht:

      print_r($treffer);

      Das liefert mir dann als Ausgabe:

      Array ( [0] => Array ( [0] => 4U2 [1] => 2t9 [2] => 1+2 ) )

      Wie muß ich den Code denn schreiben, wenn ich einfach nur stehen haben will:

      Die gefundenen Stellen sind: 4U2 2t9 1+2

      ??? *seufz*

      Gustav Gans

      1. Hi,

        Dann kommt aber einfach nur das Wort "Array" als Ausgabe.

        *seufz*, natuerlich - das kommt immer, wenn du ein Array mittels echo auszugeben versuchst.

        print_r($treffer);

        Das liefert mir dann als Ausgabe:

        Array ( [0] => Array ( [0] => 4U2 [1] => 2t9 [2] => 1+2 ) )

        Na also, das ist doch ganz leicht erkennbar, ein Array mit zwei Dimensionen.

        Wie muß ich den Code denn schreiben, wenn ich einfach nur stehen haben will:

        Die gefundenen Stellen sind: 4U2 2t9 1+2

        Greife auf die Werte des Arrays zu, welches dein Array auf zweiter Ebene enthaelt.

        MfG ChrisB

        --
        „This is the author's opinion, not necessarily that of Starbucks.“
        1. Hallo!

          *seufz*, natuerlich - das kommt immer, wenn du ein Array mittels echo auszugeben versuchst.

          Sorry, das verstehe ich nicht. $treffer ist in dem Fall das Ergebnis. Das ist ein Array, soweit ist mir das klar. Aber ich habe ja nicht echo $treffer; im Code gehabt, sondern

          foreach($treffer as $wert)  
           {  
            echo $wert."\n";  
           }
          

          und das müßte mir ja die einzelnen Teile eines Arrays ausliefern. (Siehe forech bei Arrays im quakenet php Tutorial.)

          Array ( [0] => Array ( [0] => 4U2 [1] => 2t9 [2] => 1+2 ) )

          Na also, das ist doch ganz leicht erkennbar, ein Array mit zwei Dimensionen.

          Oje. :-( Ich lerne php mit besagtem Tutorial und da steht nirgends was über "Dimensionen" bei Arrays. Kannst Du mir eine gute Seite nennen, wo ich mehr dazu lernen kann als Anfänger? Momentan hab ich keine Ahnung, was Dimensionen bei Arrays bedeutet.

          Dann kann ich Dein

          Greife auf die Werte des Arrays zu, welches dein Array auf zweiter Ebene enthaelt.

          sicher verwirklichen.

          Gustav Gans

          1. Hallo

            Sorry, das verstehe ich nicht. $treffer ist in dem Fall das Ergebnis. Das ist ein Array, soweit ist mir das klar.

            ChrisB hat dir doch schon den Hinweis gegeben. Es handelt sich bei dir um ein zweidimensionales Array.
            Daher bringt die Ausgane wieder "Array" weil dein $wert nochmals ein Array ist.
            Du könntes um bei deinem Beispiel zu bleiben es auch so machen:

            foreach($treffer as $wert)
             {
              foreach($wert as $values){
                echo $values . "<br>";
              }
             }

            viele Grüße
            hawk

            1. Hallo!

              ChrisB hat dir doch schon den Hinweis gegeben. Es handelt sich bei dir um ein zweidimensionales Array.

              Und ICH hab daraufhin gesagt, dass ich mit diesem Begriff nichts anzufangen weiß bisher und mir der Hinweis deshalb (derzeit) nicht weiterhilft.

              Daher bringt die Ausgane wieder "Array" weil dein $wert nochmals ein Array ist.
              Du könntes um bei deinem Beispiel zu bleiben es auch so machen:

              foreach($treffer as $wert)
              {
                foreach($wert as $values){
                  echo $values . "<br>";
                }
              }

              Ich DENKE; ich habs halbwegs verstanden jetzt. Habe es SO gelöst =>

              preg_match_all("#\d\D\d#",$text,$treffer);  
              foreach($treffer[0] as $wert)  
               {  
                echo $wert."\n";  
               }
              

              Danke für den Hinweis! So, nun ist mein Wissen über Arrays wieder größer und ich hab das mit dem preg_match_all besser verstanden. Für mein ursprüngliches Vorhaben ist aber offensichtlich preg_replace das Mitel der Wahl. Gut, dann werd ich mich jetzt damit beschäftigen. :-)

              Gustav Gans

              1. Hallo,
                na also, dein Ansatz war ja garnicht schlecht.

                Nur noch eine kleine Hilfestellung. Ich hatte mir mal eine Funktion gemacht um text in einer Datei zu ersetzen. Vielleicht hilft dir das ja weiter.

                function replace_all($string1, $string2, $filename) {
                   $fp = fopen( $filename, 'r');
                   $contents = fread($fp, filesize($filename));
                   fclose($fp);
                   $massreplace = preg_replace("#$string1#i", $string2, $contents);
                   $fp = fopen($filename, 'w');
                   fputs($fp, $massreplace);
                   fclose($fp);
                }

                viele Grüße
                hawk

                1. Hallo!

                  Für mein ursprüngliches Vorhaben ist aber offensichtlich preg_replace das Mitel der Wahl.

                  na also, dein Ansatz war ja garnicht schlecht.

                  Nur noch eine kleine Hilfestellung. Ich hatte mir mal eine Funktion gemacht um text in einer Datei zu ersetzen. Vielleicht hilft dir das ja weiter.

                  function replace_all($string1, $string2, $filename) {
                     $fp = fopen( $filename, 'r');
                     $contents = fread($fp, filesize($filename));
                     fclose($fp);
                     $massreplace = preg_replace("#$string1#i", $string2, $contents);
                     $fp = fopen($filename, 'w');
                     fputs($fp, $massreplace);
                     fclose($fp);
                  }

                  Du hast mich auf die falsche Spur geschickt. Nachdem ich es ja einfach ersetzen will, führt mich preg_replace nicht zum Ziel, sondern zur Fehlermeldung "Delimiter must not be alphanumeric or backslash".

                  Um mein ursprüngliches Vorhaben zu realisieren, brauche ich eigentlich nur str_replace!

                  <?php  
                   $text="Das ist doch Schund, sagte Mutter, als sie das Buch fand. Na und, meinte Peter. Das ist rund und nicht eckig, also halt bitte Deinen Mund, Mutter! So ein Verhalten löst bei mir Verwunderung aus";  
                   $textneu=str_replace("und","<span class=\"test\">und</span>",$text);  
                   echo"<p>".$textneu."</p>\n";  
                  ?>
                  

                  Und funktioniert!

                  Danke trotzdem!

                  Gustav Gans

                  1. Hallo

                    Du hast mich auf die falsche Spur geschickt. Nachdem ich es ja einfach ersetzen will, führt mich preg_replace nicht zum Ziel, sondern zur Fehlermeldung "Delimiter must not be alphanumeric or backslash".

                    Was heisst da auf die falsche Spur geschickt!!
                    Du kannst dein Problem genausogut auch mit preg_replace lösen. Die Fehlermeldung hat damit nichts zu tun.

                    Auch danke

                    viele Grüße
                    hawk

                    1. Hi!

                      Was heisst da auf die falsche Spur geschickt!!

                      Das war aber NICHT böse gemeint von mir!

                      Du kannst dein Problem genausogut auch mit preg_replace lösen.

                      Ohne, mit regulären Ausdrücken zu arbeiten, wenn ich nur eine fixe Zeichenkombination ersetzen will? Da sprechen 99% alles GOOGL-Funde für str_replace und gegen preg_replace. Du kannst mir gerne zeigen, wie es besser geht! :-)

                      Die Fehlermeldung hat damit nichts zu tun.

                      Ich wollte damit ja auch nicht sagen, daß preg_replace per se falsch ist.

                      Gustav Gans

                      1. Hi!

                        Ich habe eine weitere Frage zu Arrays und hänge sie, da themenbezogen, gleich zu meinem gestrigen Thread an:

                        Was ist der Unterschied zwischen:

                        $verein1=array("Hans","Georg","Maria");

                        und

                        $verein2=array(Hans,Georg,Maria);

                        Ist eine der beiden Schreibweisen besser, angesehener, gebräuchlicher ... oder ist eine der beiden Schreibweisen falsch?

                        Mit der Funktion var_dump bekomme ich in BEIDEN Fällen ein ABSOLUT gleiches Ergebnis, nämlich:

                        array(3) { [0]=>  string(4) "Hans" [1]=>  string(5) "Georg" [2]=>  string(5) "Maria" }

                        Drum würd ich gerne wissen, ob es egal ist, für welche Schreibweise ich mich entscheide und wenn nicht, warum.

                        Danke!

                        Gustav Gans

                        1. Ich habe mir überlegt, was die eleganteste Methode ist, die Teile eines Arrays so auszugeben, daß nach jedem aufgezählten Element ein Beistrich kommt, nach dem vorletzten ein "und" und nach dem letzten ein Punkt. Unabhängig von der Anzahl der Elemente des Arrys. Mein Ergebnis funktioniert, ich möchte nur wissen, ob es einfacher/eleganter gegangen wäre oder ob das so OK ist:

                          <?php  
                           $obst=array("Apfel","Banane","Melone","Orange","Kiwi","Mango","Erdbeere","Heidelbeere","Grapefruit");  
                           $anzahl=count($obst);  
                           $zaehler=0;  
                           echo"<p>Im Obstkorb findet man folgendes Obst: ";  
                           foreach($obst as $wert)  
                            {  
                             echo $wert;  
                             if($zaehler==$anzahl-2)  
                              {  
                               echo" und ";  
                              }  
                             else  
                              {  
                               if($zaehler==$anzahl-1)  
                                {  
                                 echo".</p>\n";  
                                }  
                               else  
                                {  
                                 echo", ";  
                                }  
                              }  
                             $zaehler+=1;  
                            }  
                          ?>
                          
                        2. Was ist der Unterschied zwischen:

                          $verein1=array("Hans","Georg","Maria");

                          und

                          $verein2=array(Hans,Georg,Maria);

                          "Hans" ist ein String-Literal
                          Hans ist ein Verweis auf eine Konstante

                          Ist eine der beiden Schreibweisen besser, angesehener, gebräuchlicher ... oder ist eine der beiden Schreibweisen falsch?

                          Die zweite ist falsch. Aber weil es PHP ist, lässt PHP solche Uneindeutigkeiten und kleine Fehler durchgehen:

                          "Falls Sie eine undefinierte Konstante verwenden, nimmt PHP an, dass Sie den Namen der Konstanten selbst meinen, so als ob Sie sie als einen string (CONSTANT vs "CONSTANT") aufgerufen hätten. Falls das passiert, wird Ihnen ein Fehler vom Typ E_NOTICE ausgegeben."

                          Ein Grund, warum du beim Programmieren immer die Fehleranzeige anschalten solltest:

                          error_reporting(E_ALL | E_STRICT);

                          Mathias

                          1. Danke für die Erklärung und den Hinweis!

                            $verstandenhabe=true;

                            :-)

                      2. Hello,

                        Ohne, mit regulären Ausdrücken zu arbeiten, wenn ich nur eine fixe Zeichenkombination ersetzen will? Da sprechen 99% alles GOOGL-Funde für str_replace und gegen preg_replace. Du kannst mir gerne zeigen, wie es besser geht! :-)

                        Mit str_replace() kannst Du nur dann zum Ziel kommen, wenn der Text selber keine HTML-Elemente und Text enthält, sondern nur Plaintext.

                        Liebe Grüße aus Syburg bei Dortmund

                        Tom vom Berg

                        --
                        Nur selber lernen macht schlau
                        http://bergpost.annerschbarrich.de
                2. Hello,

                  Nur noch eine kleine Hilfestellung. Ich hatte mir mal eine Funktion gemacht um text in einer Datei zu ersetzen. Vielleicht hilft dir das ja weiter.

                  Diese Funktion ist nicht ok.

                  function replace_all($string1, $string2, $filename)

                  {

                  $fp = fopen( $filename, 'r');                    ## hier öffnest Du eine Datei,

                  ## um sie zu lesen
                  #>    $contents = fread($fp, filesize($filename));    ## Hier lässt Du die Datei zum zweiten
                                                                        ## Mal öffen und einlesen
                       if (!fp) return false;                           ## Konnte die Datei geöffent werden?
                       if (!flock($fp,LOCK_EX)) return false;           ## Konnte die Datei gesperrt werden?

                  $fsize = filesize($fp);                          ## Größe der Datei bestimmen une merken

                  if ($fsize == 0)                                 ## Datei lesen würde bei PHP einen
                       {                                                ## einen fehler verursachen, wenn sie
                           fclose($fp);                                 ## leer ist. PHP.Entwickler haben eine
                           return true;                                 ## merkwürdige Auffassung von Fehler-
                       }                                                ## behandlung

                  $content = fread($fp,$fsize);                    ## Datei vollständig auslesen
                                                                        ## bei http:// als Schleife ausführen!

                  #>    fclose($fp);                                    ## das darfst Du jetzt noch nicht machen!

                  $massreplace = preg_replace("#$string1#i", $string2, $content);

                  #>    $fp = fopen($filename, 'w');                    ## das ist überflüssig, weil die Datei
                                                                        ## jetzt noch offen ist
                  #>    fputs($fp, $massreplace);                       ## Das würde die Datei zum zweiten Mal
                                                                        ## zum Schreiben öffen und ist damit
                                                                        ## unsinnig
                       fseek($fp,0,SEEK_SET);                           ## Dateizeiger auf den Anfang zurückstellen
                       fwrite($fp, $content);                           ## neuen Content zurückschreiben
                       ftruncate($fp,strlen($content));                 ## Dateilänge auf die _Bytelänge_ des
                                                                        ## Content anpassen, also _nicht_
                                                                        ## mb_strlen() verwenden, auch wenn der Inhalt
                                                                        ## UTF-8-codiert ist!

                  fclose($fp);                                     ## Datei schlißen und dadurch automatisch

                  ## entsperren.
                       return true;

                  }

                  wenn man die Länge der Datei in der Funktion ein zweites Mal abfragen wollte, müsste man vorher
                  http://www.php.net/manual/en/function.clearstatcache.php aufrufen.

                  http://www.php.net/manual/en/function.ftruncate.php

                  Die Fehlerbehandlung ist hier auch noch nicht vollständig, denn theoretisch kann während jedes Lese- und Schreibvorganges das Handle ungültig werden oder sonstige Dinge geschehen, die das Lesen oder Schreiben der Datei unmöglich machen. Das hängt u.a. vom OS ab, auf dem das FS läuft.

                  Liebe Grüße aus Syburg bei Dortmund

                  Tom vom Berg

                  --
                  Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                  1. Ich würde eher zu den einfachen file_get_contents und file_put_contents tendieren als Low-Level-Gewurschtel mit Dateizeigern:
                    http://de3.php.net/manual/en/function.file-get-contents.php
                    http://de3.php.net/manual/en/function.file-put-contents.php

                    Mathias

                    1. Hello,

                      Ich würde eher zu den einfachen file_get_contents und file_put_contents tendieren als Low-Level-Gewurschtel mit Dateizeigern:

                      http://de3.php.net/manual/en/function.file-get-contents.php
                      http://de3.php.net/manual/en/function.file-put-contents.php

                      Ja, aber was ist denn dann mit der Kapselung der Operationen in einer atomaren Aktion?
                      http://aktuell.de.selfhtml.org/artikel/programmiertechnik/dateisperren/

                      Liebe Grüße aus Syburg bei Dortmund

                      Tom vom Berg

                      --
                      Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
                    2. Hello,

                      Ich würde eher zu den einfachen file_get_contents und file_put_contents tendieren als Low-Level-Gewurschtel mit Dateizeigern:
                      http://de3.php.net/manual/en/function.file-get-contents.php
                      http://de3.php.net/manual/en/function.file-put-contents.php

                      Das wäre eigentlich mal eine Aufgabe für einen Objektorientierten :-)

                      file.use()
                        file.getcontents()       = lock_sh + output + unlock
                        file.altercontents()     = lock_ex + read + alter + write + unlock
                        file.putcontents()       = ...
                        file.appendcontents()
                        file.unuse()

                      usw.

                      Nur so als Denkansatz. Einige Ideen werden da ja schon durch POSIX-Streams abgedeckt, aber eben nicht alle! Und auf Microbensoftware muss es ja auch noch funktionieren. Ob es noch weitere OSse *) gibt, die für PHP relevant sind, weiß ich nicht

                      Das Problem wird sein, dass niemand wirklich entscheiden mag. wann eine atomare Operation beginnt ud wann sie zu enden hat, um möglichst wenig Störung ins System zzu bringen.

                      *) Ich habe das gelesene mit dem Plural-s :-))

                      Liebe Grüße aus Syburg bei Dortmund

                      Tom vom Berg

                      --
                      Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
          2. Zweidimensionaler Array = verschachtelter Array. Ein Array, der wiederum Arrays als Elemente enthält.

            $treffer ist in dem Fall das Ergebnis. Das ist ein Array, soweit ist mir das klar. Aber ich habe ja nicht echo $treffer; im Code gehabt, sondern

            foreach($treffer as $wert)

            {
              echo $wert."\n";
            }

            
            >   
            > und das müßte mir ja die einzelnen Teile eines Arrays ausliefern.  
              
            Ja, aber diese Elemente des Arrays sind wiederum Arrays.  
              
            
            > > > Array ( [0] => Array ( [0] => 4U2 [1] => 2t9 [2] => 1+2 ) )  
              
            arr[0][0] würde dir 4U2 geben  
              
            
            > Momentan hab ich keine Ahnung, was Dimensionen bei Arrays bedeutet.  
              
            $zweidimensionalerArray = array(  
               array(1, 2, 3),  
               array(4, 5, 6)  
            );  
              
            $zweidimensionalerArray[0][0] == 1  
            $zweidimensionalerArray[1][2] == 6  
            usw.  
              
            Mathias
            
            -- 
            [JavaScript-Erweiterung für das SELFHTML-Forum](http://forum.de.selfhtml.org/js/doku/)
            
            1. Danke für die zusätzliche Erklärung, es wird mir langsam immer klarer!

              Gustav Gans

  3. Hello,

    Also daß ich mittels php in den Text überall dort ein <span style="..."> vor und ein </span> nach den entsprechenden Stellen einbaue.

    Dann ersetze den text doch einfach mit
    http://www.php.net/manual/de/function.str-ireplace.php

    $text = file_get_contents($source);

    $text = str_ireplace($suchbegriff, "<span style="...">$suchbegriff</span>", $text);

    echo $text;

    Problematisch wird das allerdings, wenn der Text selber schon HTML-Elemente enthält.
    Das muss man der Verwenung von preg_replace() aber auch beachten!

    Liebe Grüße aus Syburg bei Dortmund

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de