Über mich

Startseite arrow Tipps & Tricks arrow Einen String kürzen ohne Wörter abzuschneiden

Einen String kürzen ohne Wörter abzuschneiden

Donnerstag, 21. Februar 2008
Geschrieben von Armin Vieweg
Einen Text in PHP auf eine bestimmte Länge zu kürzen ist recht einfach. Wie dabei jedoch berücksichtigt wird, dass das letzte Wort nicht einfach abgeschnitten wird, erfahrt ihr hier.


Mit dem PHP-Befehl substr kann man recht einfach einen String auf eine bestimmte Zeichenanzahl kürzen. Der entsprechende Befehl dafür sähe so aus:

$a = substr('Ich bin ein Text.', 0, 10);


Ausgegeben würde also "Ich bin ei". Die 10 gibt an wie viele Zeichen, die 0 ab welchem Zeichen der String angezeigt werden soll. In diesem Fall: ab dem 0. Zeichen sollen 10 in die Variable $a geladen werden.

Doch wie ihr schon seht wird das Wort "ein" in diesem Fall beschnitten.

Für manche sicher irrelevant, doch möchte man auf seiner Internetseite seriös Informationen bereitstellen, bietet es sich an etwas mehr Quellcode zu verwenden und so das letzte Wort noch auszuschreiben, auch wenn die Zeichenbegrenzung mittendrin endet. Dafür müssen wir mehrere Schritte vollziehen.



Den String splitten ohne Wörter zu verstümmeln
Als erstes fügen wir mit dem Befehl wordwrap ein Zeichen ein, alle paar Buchstaben.

$text = wordwrap($langertext, 200, "\0")


In diesem Beispiel wird alle 200 Zeichen ein weiteres hinzugefügt und zwar in diesem Fall das ASCII-Zeichen Nr. 0. Dieses existiert nicht, daher ist es nahezu ausgeschlossen, dass es sich zufällig im String befindet. Wir brauchen aber ein eindeutiges Zeichen, um es mit preg_replace später wiederzufinden.

Das besondere an dem wordwrap-Befehl ist, dass es die Wörter nicht abschneidet. Müsste von Rechts wegen nach 200 Zeichen das "\0" eingefügt werden, wartet PHP bei diesem Befehl bis das aktuelle Wort zu Ende ist und fügt es erst dahinter ein.

Jetzt haben wir also einen String, bei dem nach jedem 200. Zeichen (oder mehr, je nach dem ob ein Wort im Weg war oder nicht) ein ASCII-Code 0 eingefügt wurde.


Mit regulären Ausdrücken nach dem ASCII-Zeichen suchen und ersetzen
Als nächstes Suchen wir nach dem ASCII-Zeichen und verwenden dafür einen regulären Ausdruck.
$kurzertext = preg_replace('/^(.*?)\0(.*)$/is', '$1', $text);

Hier wird jetzt nach dem ASCII-Zeichen 0 gesucht.

/^(.*?)\0(.*)$/is

Wir teilen damit den String sozusagen auf. Rot bedeutet alle Zeichen, egal wie viele vor \0, blau alle Zeichen, egal wie viele danach.

Da \0 sich durchaus öfters im String befinden kann, da alle 200 Zeichen dieses \0 eingefügt wird, müssen wir dem roten Teil noch sagen, dass es "nicht-gierig" sein soll. Ansonsten würde es nämlich bis zum letzten auftretenden \0 die Zeichen einlesen. Das machen wir in dem wir ein ? dahinter platzieren.

Dadurch dass wir den roten und blauen Teil in Klammern gesetzt haben, können wir beim Ersetzen auf diese Inhalte mit $1 und $2 zurück greifen. In $1 stehen dann alle Zeichen vor dem ersten \0, in $2 alle Zeichen danach. $2 interessiert uns für unser jetziges Vorhaben aber nicht.



Zusammenfassung
Wir können diese Reihe von Befehlen auch zusammenfassen in:
preg_replace('/^(.*?)\\0(.*)$/is', '$1', wordwrap($result['Description'], 200, "\\0"));

Ich hoffe den Lösungsvorgang einigermaßen verständlich erklärt zu haben. Für alte PHP-Hasen ist das alles eh uninteressant, da ich mich mit dem Thema aber jetzt intensiver beschäftige, möchte ich Euch daran teilhaben lassen :)


Links

PHP-Befehl: wordwrap





  Kommentare (6)
 1 Geschrieben von: Moe, am 21.02.2008 um 10:41
Sehr schön erklärt - wirklich. 
 
Cool sind auch die Inline-Google-Adsense, die auch lekkere STRINGS anbieten ;o)
 2 Geschrieben von: Armin Vieweg, am 21.02.2008 um 10:52
;-)
 3 Geschrieben von: startcss, am 16.08.2008 um 14:00
In der Zusammenfassung fehlt bei preg_replace() als Ersatzparameter das "$1"... 
 
Ich denke es für die Performance besser sein, wenn man statt preg_replace eine Kobination aus strpos() und substr() nehmen würde: 
 
$wordwrap = wordwrap($result['Description'], 200, "\0"); 
$str = substr($wordwrap, 0, strpos($wordwrap, '\0'));
 4 Geschrieben von: Armin Vieweg, am 16.08.2008 um 16:26
Danke startcss für den Hinweis. Irgendwie hat diese Code-Hervorhebung das $1 nicht ausgegeben. 
 
Gruß 
Armin
 5 Geschrieben von: Hahni, am 28.10.2008 um 18:44
Ich habe das ganze nun so gemacht: 
 
$text=wordwrap($text, 85, "WRAPWRAPWRAP"); 
$text=explode("WRAPWRAPWRAP",$text); 
echo "$text[0]";  
 
Es gab scheinbar Probleme mit dem ASCII-Zeichen 0 auf meiner CentOS-Installation.
 6 Geschrieben von: Florian, am 25.08.2011 um 18:25
Der Artikel ist zwar schon etwas älter, aber hat mir deine tolle Erklärung doch jetzt auch noch geholfen :). 
 
Vielen Dank !
Letzte Aktualisierung ( Samstag, 16. August 2008 )
 
< Zurück   Weiter >