:d
Hi @all!
Hier wird in kürze ein Tutorial mit dem Titel "Eine Einführung in den Einsatz der Tokenizer-Funktion in PHP" von Steffen zu finden sein.
Ich wünsche gute Unterhaltung
Gruss
Jan
:d
“My software never has bugs. It just develops random features ...”
» DevShack - die Website des freien Webentwicklers Boris
Tokenizer
Warum dieses Tutorial ?
Bei meiner Suche im Netz habe ich sehr wenig Information über das Thema gefunden.
Das ist nicht gerechtfertigt, und daher möchte ich hier einen Einstieg bieten.
Wer sich das mal anschaut, wird sicher einige Ideen bekommen, was man damit noch so alles anstellen kann.
Mich hat das Thema inspiriert und deshalb möchte ich euch daran teilhaben lassen.
Was ist eigentlich ein Tokenizer ?
Der Begriff Token heisst wörtlich übersetzt Zeichen. Es ist sozusagen das kleinste Teilchen was wir kennen.
Ein Tokenizer macht also nichts anderes, als irgendeine Vorlage in seine einzelnen Zeichen zu zerlegen.
Dabei werden die einzelnen Zeichen auch noch untersucht und der Typ wird bestimmt.
Wenn wir also einen Tokenizer benötigen, dann geht es darum, einen Text in seine einzelnen "Zeichen" zu zerlegen, um mit diesen Zeichen irgendetwas anzufangen.
Wozu brauchen wir das ?
Nun, es gibt verschiedene Problemstellungen, die einen Tokenizer benötigen.
So wollen wir z.B. einen Text zerlegen und eine Wortliste erstellen. Dies machen alle Forenscripte, um die Suche zu beschleunigen.
Oder wir wollen irgendeinen Text parsen. Parsen heisst ja nichts anderes, als den Text zu übersetzen bzw. nach Schlüsselwörtern zu suchen und darauf zu reagieren.
Dabei ist es völlig unerheblich, ob es sich um PHP, SQL, HTML, CSS, CSV, XML etc. handelt. All diese Vorlagen basieren auf Texte, die Schlüsselwörter enthalten.
Man kann sich vorstellen, wenn man das alles händisch programmieren will, der Aufwand sehr gross ist.
Glücklicherweise hat PHP seit Version 4.3.3 den Tokenizer eingebaut, die wenigsten werden damit schonmal in Berührung gekommen sein.
Ich denke das wird sich nach diesem Tutorial ändern, denn der Tokenizer ist nicht nur genial, sondern auch genial einfach
Der PHP-Tokenizer
Der PHP-Tokenizer kennt gerade mal 2 Befehle:
token_get_all()
token_name()
Der erste Befehl zerlegt die gegebene Vorlage in ihre Tokens.
Der Rückgabewert ist ein Array.
Ist das entdeckte Token ein einzelnes Zeichen wie ",;:!?=" etc., so steht in dem Arrayindex nur dieses Zeichen.
Ist das Token ein Wort oder ein erkannter Teil, so steht in dem Arrayindex ein weiteres Array mit der id (was wurde erkannt) und dem Token.
Jetzt ein kleiner Trick, damit wir den Tokenizer auch dazu bekommen, alles zu parsen.
Der Tokenizer wurde dazu entwickelt, PHP-Text zu zerlegen. Nehmen wir einen normalen Text, so wird er vom Tokenizer als T_INLINE_HTML interpretiert und das entspricht einer Kommentarzeile.
Er würde also gar nicht den Text in die kleinstmöglichen Tokens zerlegen.
Also gaukeln wir dem Tokenizer einen Code vor.
Der Code beginnt mit <? und endet mit ?>. Jetzt funktioniert der Tokenizer mit jeder Vorlage !
Das einfachste ist, wir schauen uns ein kleines Beispiel an:
Wenn wir uns das Array $arr anschauen, sehen wir, wie der Tokenizer gearbeitet hat:PHP-Code:$arr=token_get_all("<?Hallo, schön hier !?>");
Der Tokenizer hat die Vorlage in 10 Tokens aufgeteilt.Code:Array ( [0] => Array ( [0] => 353 [1] => Array ( [0] => 304 [1] => Hallo ) [2] => , [3] => Array ( [0] => 356 [1] => ) [4] => Array ( [0] => 304 [1] => schön ) [5] => Array ( [0] => 356 [1] => ) [6] => Array ( [0] => 304 [1] => hier ) [7] => Array ( [0] => 356 [1] => ) [8] => ! [9] => Array ( [0] => 355 [1] => ?> ) )
Sofort sieht man, das zweimal ein einzelnes Zeichen entdeckt wurde:
Element [2] und [8] - das sind die Zeichen , und !
Alle anderen Elemente sind Arrays. Wir sehen im Index [0] immer eine Zahl und im Index [1] das Token.
Was bedeuten denn die Zahlen ?
Das ist die ID des erkannten Tokens. Auffällig ist auch, das das Leerzeichen auch ein erkanntes Token darstellt.
Doch was für Tokens hat er denn jetzt erkannt ? Muss ich in einem schlauen Buch nach der Zahl suchen ?
Und hier kommt die 2. Tokenizer-Funktion zum Zuge : token_name()
Sie gibt uns den (Konstanten-)Namen des Token zurück.
Wir basteln uns einen Mini-Parser und schauen uns das Ergebnis mal an:
Die Ausgabe sieht so aus:PHP-Code:<?php
$test="<?Hallo, schön hier !?>";
$arr=token_get_all($test);
foreach($arr as $token) {
if(!is_array($token)) { // kein Array, also ein einzelnes Zeichen
echo 'Zeichen gefunden :'.$token.'<br>';
} else {
//erkannte Tokens sind im zweidimensionalen Array
list($id,$tok)=$token;
echo 'Token gefunden '.$id.' ('.token_name($id).'): '.htmlentities($tok).'<br>';
}
}
?>
Wir sehen, das alle Worte als T_STRING erkannt werden.Code:Token gefunden 353 (T_OPEN_TAG): <? Token gefunden 304 (T_STRING): Hallo Zeichen gefunden :, Token gefunden 356 (T_WHITESPACE): Token gefunden 304 (T_STRING): schön Token gefunden 356 (T_WHITESPACE): Token gefunden 304 (T_STRING): hier Token gefunden 356 (T_WHITESPACE): Zeichen gefunden :! Token gefunden 355 (T_CLOSE_TAG): ?>
Das Leerzeichen ist T_WHITESPACE.
Somit haben wir alle Grundlagen des Tokenizers kennengelernt und machen uns an zwei Praxisbeispiele.
1. Ein WortzählerDie Umsetzung zeigt nur den Ansatz, das kann man beliebig erweitern.
2. Ein Parser mit Highlight-Funktion
Der Wortzähler
In diesem Beispiel geht es darum, die Worte zu zählen und somit ein Dictonary zu erstellen.
Als Vorlage nehmen wir uns einen beliebigen Text.
Der Quelltext könnte jetzt so aussehen:
Ein Parser mit Highlight-FunktionPHP-Code:<?php
$test='<?
Nach dem Rückzug von Heide Simonis deutet in Schleswig-Holstein vieles auf eine Große Koalition unter CDU-Mann Carstensen hin. Denn die FDP hat kein Interesse an einem Ampelbündnis, und sowohl Südschleswigscher Wählerbund als auch SPD erachten das Modell einer tolerierten Minderheitsregierung für gescheitert.
Simonis: Abschied nach zwölf Jahren
Kiel - "Dieses gemeinsame Projekt ist jetzt durch einen feigen Heckenschützen zu Fall gebracht worden", hieß es heute in einer Erklärung der SSW-Landtagsabgeordneten Anke Spoorendonk und Lars Harms sowie der Landesvorsitzenden Gerda Eichhorn. Simonis sei eine verlässliche Partnerin gewesen, die einer Minderheitsregierung Tatkraft und Stabilität verliehen hätte.
Auch die SPD will vorerst keinen erneuten Versuch für ein Dreier-Bündnis mit dem SSW unternehmen. Solange der Abweichler nicht bekannt sei, könne er keinen Kandidaten bei nur einer Stimme Mehrheit ins Rennen um die Wahl eines neuen Ministerpräsidenten schicken, sagte SPD-Fraktionschef Lothar Hay am Rande einer Parteiratssitzung in Kiel. "Das wäre politischer Kamikaze-Flug." Hay bekräftigte, dass mit allen Parteien Sondierungsgespräche über die Bildung einer neuen Landesregierung geführt werden sollten. Bereits nächste Woche wolle sich die SPD mit der CDU darüber unterhalten. Die größte Differenz zur CDU liege in der Bildungspolitik.
?>';
$woerter=Array();
$arr=token_get_all($test);
foreach($arr as $token) {
if(!is_array($token)) { // kein Array, also ein einzelnes Zeichen
//ignorieren
} else {
//erkannte Tokens sind im zweidimensionalen Array
list($id,$tok)=$token;
if(token_name($id)=="T_STRING") // uns interessieren nur die Wörter
$woerter[$tok]++;
}
}
//Wortliste sortieren
ksort($woerter);
//Wortliste anzeigen
foreach($woerter as $var => $val) {
echo "Wort '$var' kommt $val mal vor<br>";
}
?>
Vorlage ist ein kleines Perlscript.
Werden Schlüsselwörter gefunden, färben wir blau ein.
Wird ein Kommentar gefunden, färben wir grün ein.
Wird ein durch Anführungszeichen eingeschlossenen String gefunden, färben wir rot ein.
die Vorlage:
Und hier der ParserCode:#!usr/bin/perl print "Content-type: text/html\n\n"; print "Hallo,\n"; print "Ich war ein Perl-Script!";
Ich hoffe durch dieses Tutorial einige Anregungen gegeben zu haben.PHP-Code:<?php
//Perlskript laden
$script="<? ".file_get_contents("test.pl")."?>";
$arr=token_get_all($script);
foreach($arr as $token) {
if(!is_array($token)) { // kein Array, also ein einzelnes Zeichen
echo $token;
if($token==";") echo "<br>";
} else {
//erkannte Tokens sind im zweidimensionalen Array
list($id,$tok)=$token;
switch(token_name($id)) {
case "T_OPEN_TAG":
case "T_CLOSE_TAG":
//ignorieren
break;
case "T_COMMENT": // Kommentar
echo '<span style="color:green;">'.$tok.'</span><br>';
break;
case "T_CONSTANT_ENCAPSED_STRING": //Ein String in Anführungszeichen
echo '<span style="color:red;">'.$tok.'</span>';
break;
case "T_PRINT": // der Befehl print
echo '<span style="color:blue;">'.$tok.'</span>';
break;
default: // alles andere
echo $tok;
}
}
}
?>
Eine vollständige Liste der eingebauten Tokens gibt es hier
Viel Spass beim experimentieren !
Geändert von steffenk (19.03.2005 um 11:34 Uhr)
TYPO3 · MySQLDumper · dislabs
·
manche Mühlen mahlen schneller ...
"Ich habe Rücken"
Horst Schlämmer
Danke für das Tutorial. Da leuchten bei mir im Kopf doch sofort 1000 Lampen mit neuen Möglichkeiten auf.![]()
class GetProfileCustomerEntityReceiverInformationReceiverAndProgrammingInforma...{
public function __construct(){ if(!$this) die(' '); } }
http://www.thedailywtf.com/
Hi !
Ich möchte auch nochmal meinen "Senf" dazugeben. Das Beispiel mit der Perl-Datei kann verwirren! Da die beiden Sprachen einen ähnlichen Syntax haben, kann man in diesem speziellen Fall tatsächlich auf die Tokentypen korrekt reagieren. Ein "echter" Tokenizer, wie es ja der PHP-Tokenizer ist, ist auf einen bestimmten Syntax ausgelegt. Das setzen von <? und ?> ist sozusagen eine art "missbrauch"...klar... man kann den Tokenizer so nutzen - ich wollte aber nur nochmal drauf hinweisen.
Gruss
Jan
Auch von mir ein schallendes Dankeschön für die Ausführung, welche im übrigen kaum passender hätte kommen können. Am Freitag zerbrach' ich mir den Kopf mit pspell und den deutschen Umlauten, welche in Kombination mit den preg-Funktionen ausschließlich Probleme bescherten. Dank' dir kann ich ja nun wieder effektiver weiterarbeiten.![]()
Ich wußte vorher auch gar nichts über die Existenz des Tokenizers und nun hat mir gleich jemand mit Beispielen erklärt wie man sinnvoll damit umgehen kann.
Vielen, vielen Dank!![]()
Das kann ich an vielen Stellen astrein einsetzen.
was faellt euch denn dazu immer ein?
in eile kam er,
in schwarzem gewand,
aus den tiefen des waldes,
ein einsamer mann, ein geschoepf der freiheit,
ein geschoepf ohne furcht,
doch alle nannten sie ihn nur T O D
z.B.:
- Suchindex für Foren erstellen
- Suchindex für Gästebücher
- Suchindex für Newsseiten
- farbliche Gestaltung von Scriptlistings (wie PHP-Befehl hier im Board) auch in eigenen Ausgaben nutzen
- Häufigkeitsstatistiken
und wenn ich damit arbeite fällt mir bestimmt noch mehr ein.
Sehr geiles Tut. Sehr verständlich und auch nützlich. Danke!Mal sehen ob ich den Tokenizer irgendwo missbrauchen kann
![]()
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)