Philipp.: Text in einzelne Wörter splitten klappt nicht korrekt

Hi,

ich lese eine Textdatei ein und speichere den gesamten Inhalt Wort für Wort in einem Array. Als Trennungszeichen ist alles erlaubt außer [^a-zA-z;&] (; und & deswegen, damit Worte mit Umlauten nicht in der Mitte getrennt werden).

(Die Textdatei ist so aufgebaut:

pfadangabeabc.php|titel| | |text blabla
pfadangabexyz.php|titel| | |text blablubb

Benötigt wird nur der "text"-Teil.)

Die Wörter werden dann "gefiltert" und in ein neues Array gespeichert. Lese ich dieses Array aber dann aus, finde ich doch plötzlich Wörter, die vor dem Umlaut abgeschnitten sind. Ich weiß aber nicht, was da der Fehler ist. Wenn ich vor dem "Filtern" das Array ausgeben lassen scheint alles in Ordnung, aber danach nicht mehr.

Das Script sieht so aus:

  
  
<?php  
  
$datei = "data.txt"; # Datei öffnen und einlesen  
  
$zeilen = file($datei);  
$anz_zeilen = sizeof($zeilen);  
  
for ($i=0; $i<$anz_zeilen; $i++)  
{  
  list ($egala, $egalb, $egalc, $egald, $content) = split("\\|", chop($zeilen[$i]));  
  
  $inhalt = $content;  
  
  $liste = spliti('[^a-z;&]', $inhalt);  
  
  foreach ($liste as $word)  
  {  
    $prozent = (1-levenshtein(strtolower($input), strtolower($word))/max(strlen($input), strlen($word)));  
    if((levenshtein(strtolower($input),strtolower($word)) <= $focus) && $prozent >= 0.5)  
    {  
      if(!array_key_exists($word,$words))  
      {  
        $words[$word] = $prozent;  
      }  
    }  
  }  
}  
  
foreach($liste as $wort) #Array vor Filter, i.O.  
{  
  echo "$wort<br>";  
}  
  
foreach($words as $word => $prozent) #Array nach Filter, nicht i.O.  
{  
  echo "$word<br>";  
}  
  
?>  
  

Kann mir da jemand helfen?

  1. Hallo,
    ich kann dir ledier nicht helfen aber ich würde gerne wissen was folgende Zeilen machen?

    <<$prozent = (1-levenshtein(strtolower($input), strtolower($word))/max(strlen($input), strlen($word)));
        if((levenshtein(strtolower($input),strtolower($word)) <= $focus) && $prozent >= 0.5)>>

    ich hatte das bisher (levenshtein) so noch nie gesehen.

    vielen Dank
    Gruss
    hawk

    1. Hallo,
      ich kann dir ledier nicht helfen aber ich würde gerne wissen was folgende Zeilen machen?

      $prozent berechnet, zu wieviel Prozent das gesuchte Wort ($input) mit dem jeweiligen Wort ($word) aus dem Array übereinstimmt - einfach, damit ich später danach sortieren kann.

      Die if-Abfrage selektiert die Wörter ($word) nach ihrer Übereinstimmung mit dem Suchbegriff ($input). Nur wenn die Übereinstimmung mindestens 50 % beträgt und der Lev.wert weniger als $focus Zeichen beträgt, wird das Wort überhaupt als Alternative vorgeschlagen. Hintergrund: bei längeren Wörtern ist die Wahrscheinlichkeit, dass der Lev.wert größer ist höher, also gibts hier nen größeren $focus.

      Ich hoffe, dass ich mir da keinen Unsinn ausgedacht habe :D - die Resultate sehen bisher aber ganz gut aus.

  2. echo $begrüßung;

    ich lese eine Textdatei ein und speichere den gesamten Inhalt Wort für Wort in einem Array. Als Trennungszeichen ist alles erlaubt außer [^a-zA-z;&] (; und & deswegen, damit Worte mit Umlauten nicht in der Mitte getrennt werden).

    Nebensächliches: Wieso stehen da eigentlich HTML-Schreibweisen in einem Nicht-HTML-Kontext?

    [...] finde ich doch plötzlich Wörter, die vor dem Umlaut abgeschnitten sind. Ich weiß aber nicht, was da der Fehler ist.

    Den Fehler kann ich auch nicht nachvollziehen:

    list (, , , , $content) = split("\|", 'pfadangabexyz.php|titel| | |bl&ouml;dsinn und l&ouml;tzinn');
      var_dump($content);
      var_dump(spliti('[^a-z;&]', 'bl&ouml;dsinn und l&ouml;tzinn'));

    ergibt:

    string(30) "bl&ouml;dsinn und l&ouml;tzinn"
      array(3) {
        [0]=> string(13) "bl&ouml;dsinn"
        [1]=> string(3) "und"
        [2]=> string(12) "l&ouml;tzinn"
      }

    Wenn ich vor dem "Filtern" das Array ausgeben lassen scheint alles in Ordnung, aber danach nicht mehr.

    var_dump() gibt dir auch die Zeichenanzahl im String aus. Stimmt die mir den von dir gezählten Zeichen überein, oder versteckt sich da vielleicht noch irgendein Sonderzeichen?

    list ($egala, $egalb, $egalc, $egald, $content) = split("\|", chop($zeilen[$i]));

    Nebensächliches: Nicht benötigte Werte benötigen keine Dummy-Variable. Sie können einfach ausgelassen werden, nur ein Komma muss stehenbleiben.

    echo "$verabschiedung $name";

    1. Hi,

      var_dump() gibt dir auch die Zeichenanzahl im String aus. Stimmt die mir den von dir gezählten Zeichen überein, oder versteckt sich da vielleicht noch irgendein Sonderzeichen?

      Kannst du mir sagen, wo genau ich das hinpacken soll? Komme da auf keinen grünen Zweig.

      1. echo $begrüßung;

        var_dump() gibt dir auch die Zeichenanzahl im String aus. Stimmt die mir den von dir gezählten Zeichen überein, oder versteckt sich da vielleicht noch irgendein Sonderzeichen?
        Kannst du mir sagen, wo genau ich das hinpacken soll? Komme da auf keinen grünen Zweig.

        var_dump() packt man nicht hin. Man fügt es zum Zwecke einer Kontrollausgabe an der Stelle ein, an der man den Inhalt einer Variablen angezeigt bekommen möchte, damit man die eigene Vorstellung und die Wirklichkeit miteinander vergleichen kann.

        echo "$verabschiedung $name";

        1. var_dump() packt man nicht hin. Man fügt es zum Zwecke einer Kontrollausgabe an der Stelle ein, an der man den Inhalt einer Variablen angezeigt bekommen möchte, damit man die eigene Vorstellung und die Wirklichkeit miteinander vergleichen kann.

          Okay ;)

          Nur das Problem:

          var_dump auf $liste bezogen ((foreach($liste as $word) { echo vardump($word); }), liefert mir korrekte Ergebnisse. Also bei jedem Wort erhalte ich die korrekte Zeichenanzahl.

          var_dump auf $words bezogen ((foreach($words as $word) { echo vardump($word); }), liefert mir natürlich ebenso korrekte Ergebnisse, aber eben für die abgeschnittenten Wortstummel.

          Wo die umlaute verloren gehen seh ich dadurch ja nicht!?

          1. echo $begrüßung;

            var_dump auf $words bezogen ((foreach($words as $word) { echo vardump($word); }), liefert mir natürlich ebenso korrekte Ergebnisse, aber eben für die abgeschnittenten Wortstummel.
            Wo die umlaute verloren gehen seh ich dadurch ja nicht!?

            Wenn sie da offensichtlich schon verloren gegangen sind, dann musst du die Kontrollausgabe eher anwenden. Irgendeiner deiner vorherigen Verarbeitungsprozesse liefert dann ein falsches bzw. unerwartetes Ergebnis. Diesen verantwortlichen Ausdruck aufzuspüren ist das Ziel von Kontrollausgaben.

            Vielleicht ist in $words irgendwas altes drin. Du initialisierst ja dieses Array nicht explizit in deinem im Ausgangsposting zitierten Codeausschnitt. Warum da irgendwas anderes als in $liste drinstehen soll geht aus dem Code nicht hervor. Zum Nachvollziehen fehlen auch einige Variableninitialisierungen ($input, $focus).

            echo "$verabschiedung $name";

            1. Also die Variablen sehen so aus:

              $input: per URL übergebener Suchbegriff
              $focus: strlen($input);

              $list und $words werden direkt vor dem geposteten Code als neue Arrays angelegt ($.. = array();), ebenso $word = "";. Keines der Arrays oder eine Variable ändert sich danach, außer $focus (zwischen 1 und 10).

              Allerdings bin ich dem Problem vielleicht ein Stück näher. In der Textdatei habe ich einige Wörter gefunden, wo Umlaute nicht als HTML-Code ($xuml; sonder einfach als ä usw.) angegeben waren. Das habe ich geändert.

              Kurioserweise werden jetzt nur die Wortstücke ausgegeben, die hinter einem Umlaut stehen.

              Wurde also vorher von den Worten "Veränderung" und "höher" nur "Ver" und "her" ausgegeben, wird jetzt nur noch "her" ausgegeben.

              Das verwirrt mich ja eigentlich noch mehr ..

              1. ($xuml; ...

                muss natürlich "(&xuml; ..." heißen

              2. echo $begrüßung;

                Das verwirrt mich ja eigentlich noch mehr ..

                Es gibt Tätigkeiten beim Programmieren, die kann man nur allein ausführen. Beispielsweise ist das das Suchen nach einem Fehler in einer konkreten Umgebung. Deswegen versuche ich dir ja die ganze Zeit, die Kontrollausgaben ans Herz zu legen. Finde die Stelle, an der der Wert vorher noch vollständig war, und hinterher kaputt ist. Wenn du dann ein Problem mit dem Verständnis dieses Programmteils hast, versuch es mit so wenig Code wie möglich nachzubilden, aber so, dass es vollständig nachvollziehbar ist. Das kannst du dann zur Diskussion stellen und irgendwer wird es dir erklären können.

                echo "$verabschiedung $name";

                1. (schäm)

                  Ich glaube, das Problem ist behoben.

                  Dass "her" weiterhin auftaucht ist liegt daran, dass das Wort "her" einmal tatsächlich existiert ;)

                  Also, vielen Dank für die Unterstützung - wäre mal wieder leichter gewesen, wenn ich aufgepasst hätte ...

                  Nur eine Frage hab ich noch, weil du schriebst "Nebensächliches: Wieso stehen da eigentlich HTML-Schreibweisen in einem Nicht-HTML-Kontext?".

                  Was genau meinst du damit, die Umlaute &xuml;? Wie sollte man da vorgehen? Ich habe damit leider immer meine Probleme und weiß nie so recht, wann ich jetzt ä und wann &auml; oder was auch imemr benutzen sollte.

                  1. Hi,

                    Nur eine Frage hab ich noch, weil du schriebst "Nebensächliches: Wieso stehen da eigentlich HTML-Schreibweisen in einem Nicht-HTML-Kontext?".

                    Was genau meinst du damit, die Umlaute &xuml;?

                    Natuerlich. Die Daten, die du auswertest, scheinen nicht im Kontext HTML benutzt zu werden - also wieso verwendest in ihnen eine HTML-Kodierung?

                    Wie sollte man da vorgehen?

                    Eine passende Zeichenkodierung waehlen.

                    Ich habe damit leider immer meine Probleme und weiß nie so recht, wann ich jetzt ä und wann &auml; oder was auch imemr benutzen sollte.

                    Benutze ä, wann immer moeglich - und die Kruecke &auml; nur, wenn unumgaenglich (wenn also ä im HTML dargestellt werden muss, eine passende Zeichenkodierung, die dieses Zeichen enthaelt, aber nicht verwendet werden *kann*).

                    MfG ChrisB

                    1. Natuerlich. Die Daten, die du auswertest, scheinen nicht im Kontext HTML benutzt zu werden - also wieso verwendest in ihnen eine HTML-Kodierung?

                      Sollte ich also dann die Umlaute in der Textdatei ganz normal speichern und für den Fall, dass ich sie später auf meiner Seite ausgebe mit htmlentities($word) anzeigen lassen?

                      1. echo $begrüßung;

                        Natuerlich. Die Daten, die du auswertest, scheinen nicht im Kontext HTML benutzt zu werden - also wieso verwendest in ihnen eine HTML-Kodierung?
                        Sollte ich also dann die Umlaute in der Textdatei ganz normal speichern und für den Fall, dass ich sie später auf meiner Seite ausgebe mit htmlentities($word) anzeigen lassen?

                        Du musst für dich eine zu verwendende Kodierung festlegen. Diese Kodierung nimmst du beim Speichern von Dateien und beim Übertragen von Daten. Dem Empfänger gibst du über die üblichen Methoden bekannt, welche Kodierung er bekommt.

                        HTML kennt eine Ersatzdarstellung mit Entities und numerischen Zeichenreferenzen. Die wird nur dann benötigt, wenn ein Zeichen in der verwendeten Kodierung nicht vorkommt, beispielsweise das €-Zeichen in ISO-8859-1. Ansonsten kannst du jedes Zeichen in der angegebenen Kodierung direkt notieren.

                        echo "$verabschiedung $name";

                        1. Aber im Grunde wäre ich dann in jedem Fall auf der sicheren Seite, und ob ich jetzt $word oder htmlentities($word) ausgeben lasse, macht ja keine Umstände!?

                          1. echo $begrüßung;

                            Aber im Grunde wäre ich dann in jedem Fall auf der sicheren Seite, und ob ich jetzt $word oder htmlentities($word) ausgeben lasse, macht ja keine Umstände!?

                            Du bist dann auf einer besser gesicherten Seite, wenn du die verwendete Kodierung angibst. Denn dann wird dir mit hoher Wahrscheinlichkeit auch kein auf eine andere Default-Kodierung eingestellter Browser einen Strich durch die Rechnung machen, wenn er aufgrund der fehlenden Angabe irgendwas falsches verwendet. 100% Sicherheit kannst du aber auch nicht erreichen, nicht immer spielen die Browser alle Spielchen mit, die die Webanbieter mit ihnen zu treiben versuchen.

                            Es ist immer sinnvoll, für kontextgerechte Ausgaben zu sorgen. Doch das erreichst du schon mit htmlspecialchars(). Zudem musst du auch für die richtige Anwendung der Funktion htmlentities() wissen, in welcher Kodierung deine Daten vorliegen. Denn auch die kann nicht erraten, in welcher Kodierung die ihr übergebenen Daten vorliegen. Wenn du also sowieso schon wissen musst, welche Kodierung vorliegt, kannst du sie doch auch gleich richtig deklarieren und die unnötigen Entities vermeiden.

                            echo "$verabschiedung $name";

                            1. Ich seh schon, mit dem Thema muss ich mich noch einmal ernsthaft auseinandersetzen, das ist ja quasi wie ein Buch mit sieben Siegeln :)

                              Also nochmals vielen Dank für die Hilfe - wenn ich nicht weiter weiß, weiß ich ja wo ich fragen muss.