Textdatei zeilenweise nach Suchbegriffen mit PHP und der Funktion strpos durchsuchen
Da schon mal der Wunsch auftaucht(e), eine Textdatei mittels Script (Batch, PHP, VBS etc. . . .) nach Begriffen zu durchsuchen, und dabei auch
Schwierigkeiten bestehen/bestanden, das Ergebnis von strpos auszuwerten, habe ich das jetzt mal hier wie folgt mit PHP und strpos umgesetzt.
Das Script nimmt zwei Parameter entgegen:
- Den Namen einer Textdatei (Auswahl mit Select-Box)
- Ein oder mehrere Suchbegriffe in einem Textfeld
Bei Aufruf wird ein im Script angegebenes Verzeichnis incl. Unterverzeichnisse ausgelesen. Die Dateitypen, die eingelesen werden sollen, können hier
durch Angabe der Dateiendung bestimmt werden. Die Datei, die durchsucht werden soll, kann dann mittels einer Select-Box ausgewählt werden (Ein bißchen Komfort).
Mittels zwei verschachtelten while-Schleifen wird die Textdatei nun durchsucht. Die äußere Schleife spricht dabei alle Zeilen einer Textdatei an,
die innere Schleife alle eingegebenen Suchbegriffe. Bei jedem Durchlauf der äußeren Schleife wird also geprüft, ob sich ein oder mehrere,
eingegebene Suchbegriffe in dieser Zeile befinden. Bei jedem Fund wird eine Zeile in einem Array abgelegt, die folgendes beinhaltet:
- den gefundenen Suchbegriff
- die Zeilennummer
- die Positionsnummer in der Zeile
- die Textzeile
Auch wenn nur das Fragment eines Wortes eingegeben wurde (z.B. genaue Schreibweise nicht bekannt), wird das Fragment innerhalb eines Wortes in einer
Zeile gefunden. Somit wird auch diese Zeile ausgegeben.
Einigen PHP-Funktionen steht das Zeichen @ voran. Dadurch werden funktionseigene Fehlermeldungen unterdrückt, die durch eigene Fehlerroutinen
ersetzt werden (können).
Das Array $limiter_arr enthält Zeichen wie "+, -, &, ;" usw., die normalerweise in Suchmaschinen benutzt werden, um Suchbegriffe zu trennen, zu verknüpfen oder
auszugrenzen etc.. Diese Zeichen werden im Script durch ein Komma ersetzt. Weitere Zeichen bitte selber ins Array schreiben.
Wäre natürlich reizvoll, das Script so zu optimieren, dass Suchbegriffe verknüpft bzw. ausgegrenzt werden können.
Suchergebnisse von strpos auswerten
Suchergebnisse sollten laut http://de2.php.net/manual/de/function.strpos.php mit dem Operator === ausgewertet werden.
Erklärung zu diesem Operator ==> http://de2.php.net/manual/de/language.operators.comparison.php
Und los geht's . . .
. . . und End' is'.
Gruß
Günni
Schwierigkeiten bestehen/bestanden, das Ergebnis von strpos auszuwerten, habe ich das jetzt mal hier wie folgt mit PHP und strpos umgesetzt.
Das Script nimmt zwei Parameter entgegen:
- Den Namen einer Textdatei (Auswahl mit Select-Box)
- Ein oder mehrere Suchbegriffe in einem Textfeld
Bei Aufruf wird ein im Script angegebenes Verzeichnis incl. Unterverzeichnisse ausgelesen. Die Dateitypen, die eingelesen werden sollen, können hier
durch Angabe der Dateiendung bestimmt werden. Die Datei, die durchsucht werden soll, kann dann mittels einer Select-Box ausgewählt werden (Ein bißchen Komfort).
Mittels zwei verschachtelten while-Schleifen wird die Textdatei nun durchsucht. Die äußere Schleife spricht dabei alle Zeilen einer Textdatei an,
die innere Schleife alle eingegebenen Suchbegriffe. Bei jedem Durchlauf der äußeren Schleife wird also geprüft, ob sich ein oder mehrere,
eingegebene Suchbegriffe in dieser Zeile befinden. Bei jedem Fund wird eine Zeile in einem Array abgelegt, die folgendes beinhaltet:
- den gefundenen Suchbegriff
- die Zeilennummer
- die Positionsnummer in der Zeile
- die Textzeile
Auch wenn nur das Fragment eines Wortes eingegeben wurde (z.B. genaue Schreibweise nicht bekannt), wird das Fragment innerhalb eines Wortes in einer
Zeile gefunden. Somit wird auch diese Zeile ausgegeben.
Einigen PHP-Funktionen steht das Zeichen @ voran. Dadurch werden funktionseigene Fehlermeldungen unterdrückt, die durch eigene Fehlerroutinen
ersetzt werden (können).
Das Array $limiter_arr enthält Zeichen wie "+, -, &, ;" usw., die normalerweise in Suchmaschinen benutzt werden, um Suchbegriffe zu trennen, zu verknüpfen oder
auszugrenzen etc.. Diese Zeichen werden im Script durch ein Komma ersetzt. Weitere Zeichen bitte selber ins Array schreiben.
Wäre natürlich reizvoll, das Script so zu optimieren, dass Suchbegriffe verknüpft bzw. ausgegrenzt werden können.
Suchergebnisse von strpos auswerten
Suchergebnisse sollten laut http://de2.php.net/manual/de/function.strpos.php mit dem Operator === ausgewertet werden.
Erklärung zu diesem Operator ==> http://de2.php.net/manual/de/language.operators.comparison.php
Und los geht's . . .
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Worte in Textdateien suchen</title>
</head>
<body>
<?php
/*
* Callbackfunktion mit Sortierkriterien, wird von usort benötigt
*/
function cmp($a, $b) {
if ($a == $b) return 0;
return ($a > $b)? 1 : -1;
}
/*
* Ein Array zur Aufnahme der Dateien
*/
$datei_arr=array();
/*
* Die Funktion liest ein Verzeichnis incl. Unterverzeichnisse aus.
* - $verzeichnis - das soll ausgelesen werden
* - &$arr - hier wird das Array (s.o.) übergeben. Das & ist eine Referenz auf die Variable,
* die hier durch direkt von der Funktion verändert wird.
*/
function dir_rekursiv($verzeichnis, &$arr){
/*
* Diese Dateitypen sollen eingelesen werden.
*/
//$datei_typ_arr=array(0 => ".txt", 1 => ".php", 2 => ".htm", 3 => ".html");
$datei_typ_arr=array(0 => ".txt");
$handle = @opendir($verzeichnis);
while ($datei =@readdir($handle)){
if ($datei != "." && $datei != ".." ){
if (is_dir($verzeichnis.$datei)){
dir_rekursiv($verzeichnis.$datei."/", &$arr);
}else{
/*
* strrchr(string $string, string $zeichen) gibt den Text nach dem letzten Vorkommen von $zeichen incl. $zeichen zurück.
*/
$ext=strrchr($verzeichnis.$datei, ".");
/*
* Wenn $ext in dem Dateitypen-Array vorkommt, Datei im Array ablegen.
*/
if(in_array($ext, $datei_typ_arr)){
$arr=$verzeichnis.$datei;
}
}
}
}
@closedir($handle);
}
/*
* Funktionsaufruf mit Verzeichnisangabe und Variable
*/
dir_rekursiv("/www/",$datei_arr);
/*
* usort($array, Callback-Funktion) sortiert das Array.
*/
usort ($datei_arr, 'cmp');
?>
<!--
Ein Formular zur Eingabe.
/-->
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<p>Datei auswählen <select name="seldatei" title="Datei auswählen"></p>
<option selected value=""> -- Datei auswählen -- </option>
<?php
/*
* Dateinamen in der Selectbox ausgeben.
*/
foreach($datei_arr as $datei){
echo "<option value=\"$datei\">$datei</option>";
}
?>
<p></select></p>
<p>Suchbegriff(e) eingeben <input type="text" name="suche" title="Geben sie einen oder mehrere Suchbegriff(e) ein"></p>
<p><input type="submit" name="cmd" value="Suchen" title="Absenden"></p>
</form>
<?php
/*
* Mit ini_set(PARAMETER) werden Fehler/Hinweise angezeigt.
*/
ini_set('error_reporting', E_ALL|E_STRICT);
ini_set('display_errors', 'On');
/*
* Parameter der Funktion:
* - ein oder mehrere Suchbegriffe
* - einen Dateinamen
*/
function findwort($wort,$textdatei){
/*
* Wenn kein Dateiname eingegeben ist, Array mit Meldung füllen und beenden.
*/
if(strlen(trim($textdatei))==0){
$gef_zeilen_arr="Wählen sie einen Dateinamen";
return $gef_zeilen_arr;
}
/*
* Wenn kein(e) Suchbegriff(e) vorhanden sind, Array mit Meldung füllen und beenden.
*/
if(strlen(trim($wort))==0){
$gef_zeilen_arr="Geben sie einen oder mehrere Suchbegriff(e) ein";
return $gef_zeilen_arr;
}
/*
* Falls ein User (aus Versehen oder "zum Testen") Trennzeichen eingibt wie +, - & usw.,
* werden diese durch ein Komma ersetzt. Die Liste $limiter_arr nach Bedarf erweitern.
*/
$limiter_arr=array(0 => "+", 1 => ";", 2 => "|", 3 => "&", 4 => " "/* Auch Leerzeichen durch Komma ersetzen */, 5 => "-");
foreach($limiter_arr as $limiter){
$wort=str_replace($limiter, ",", $wort);
}
/*
* Suchbegriffe in $wort in einem Array ablegen.
* Enthält $wort nur ein Wort, hat das Array eben nur ein Element.
*/
$wort_arr=explode(",",trim($wort));
/*
* Textdatei zeilenweise in ein Array einlesen.
* 160 ist die Zeilenlänge, erhöhen falls nötig.
*/
$text_zeilen_arr=array();
$f = @fopen($textdatei,"r");
/*
* Wenn die Textdatei nicht geöffnet werden konnte (z.B. fehlende Rechte), Array mit Meldung füllen und beenden.
*/
if(!$f){
$gef_zeilen_arr="Datei: ".$textdatei;
$gef_zeilen_arr="Die Datei ".$textdatei." konnte nicht geöffnet werden";
return $gef_zeilen_arr;
}
while($zeile=@fgets($f,160)){
$text_zeilen_arr=$zeile;
}
@fclose($f);
/*
* Zeilenweise das Array mit der Funktion strpos durchsuchen.
* strpos arbeitet case-sensitiv, deshalb werden mit strtolower
* alle Groß- in Kleinbuchstaben umgewandelt.
*/
$gef_zeilen_arr=array();
$gef_zeilen_arr="Datei: ".$textdatei;
$i=0;
while($i<count($text_zeilen_arr)){//while 1
$k=0;
/*
* In der inneren Schleife wird nun Wort für Wort geprüft, ob es in der Textzeile vorkommt.
*/
while($k<count($wort_arr)){//while 2
$pos = @strpos(strtolower($text_zeilen_arr[$i]),strtolower($wort_arr[$k]));
/*
* Bitte den Operator "===" beachten.
*/
if($pos === false){
/*
* Wenn strpos das boolsche FALSE zurückgibt, passiert nichts.
*/
}else{
/*
* Ansonsten die Array-Zeile mit einer Meldung füllen.
* - ($i+1) - Da ein Array bei 0 beginnt, wird eine 1 aufaddiert, weil sonst die falsche Zeilennummer am Bildschirm ausgegeben würde.
* - ($pos+1) - Da strpos bei 0 anfängt zu zählen, wird eine 1 aufaddiert, weil sonst die falsche Positionsnummer am Bildschirm ausgegeben würde.
*/
$gef_zeilen_arr="Der Suchbegriff ".$wort_arr[$k]." wurde in Zeile ".($i+1)." an Position ".($pos+1)." gefunden ==> ".$text_zeilen_arr[$i];
}
$k++;
}//end while 2
$i++;
}//end while 1
/*
* Enthält das Array mind. 2 Elemente(den Dateinamen und eine oder mehr gefundene Textzeilen), so wird das Array zurückgegeben.
* Ansonsten wird das Array mit einer Meldung gefüllt und zurückgegeben.
*/
if(count($gef_zeilen_arr)>1){
return $gef_zeilen_arr;
}else{
$gef_zeilen_arr="Der/die Suchbegriff(e) \"$wort\" wurde(n) nicht gefunden";
return $gef_zeilen_arr;
}
}
/*
* Ist das Formular gesendet, gibt die Funktion ein Array zurück, deshalb mit foreach ausgeben.
*/
if(isset($_POST['suche'])){
$erg_arr=findwort($_POST['suche'],$_POST['seldatei']);
foreach($erg_arr as $erg){
/*
* Die gefundenen Textzeilen mit der Funktion htmlspecialchars ausgeben, falls die durchsuchte Textdatei
* eine HTML/PHP - oder ähnliche Datei ist.
*/
echo "<pre>".htmlspecialchars($erg)."</pre>";
}
}
?>
</body>
</html>
. . . und End' is'.
Gruß
Günni
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 167073
Url: https://administrator.de/contentid/167073
Ausgedruckt am: 21.11.2024 um 22:11 Uhr
3 Kommentare
Neuester Kommentar
Hallo Günni,
erst einmal vielen Dank, für deine Anleitung! Die wird sicher vielen von Nutzen sein, die mit PHP arbeiten.
deswegen auch ein hilfreich von mir
Aber, da du VBS und Co erwähnst: das läßt sich mit weniger Zeilen auch erfassen.
Ganz kurzes Bespiel:
Mich persönlich erschlägt der Code etwas. Aber eventuell liegt es daran, dass ich von PHP keine Ahnung habe.
Viele Grüße
Tsuki
erst einmal vielen Dank, für deine Anleitung! Die wird sicher vielen von Nutzen sein, die mit PHP arbeiten.
deswegen auch ein hilfreich von mir
Aber, da du VBS und Co erwähnst: das läßt sich mit weniger Zeilen auch erfassen.
Ganz kurzes Bespiel:
SuchText = LCase("Im vbarchiv gibt es jede Menge Tipps und jede Menge Infos.")
SuchZeichen = LCase("gibt")
for i = 1 to len(Suchtext)
temp = mid(Suchtext,i,Len(SuchZeichen))
if temp = SuchZeichen then temp1 = temp1 & i & vbcrlf
next
msgbox temp1
Viele Grüße
Tsuki