Top-Themen

Aktuelle Themen (A bis Z)

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Textdatei zeilenweise nach Suchbegriffen mit PHP und der Funktion strpos durchsuchen

Mitglied: Guenni

Guenni (Level 2) - Jetzt verbinden

27.05.2011, aktualisiert 12.06.2011, 9078 Aufrufe, 3 Kommentare, 2 Danke

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 . . .

01.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
02.
<html> 
03.
<head> 
04.
<title>Worte in Textdateien suchen</title> 
05.
</head> 
06.
<body> 
07.
<?php 
08.
/* 
09.
* Callbackfunktion mit Sortierkriterien, wird von usort benötigt 
10.
*/ 
11.
function cmp($a, $b) { 
12.
 if ($a == $b) return 0; 
13.
 return ($a > $b)? 1 : -1; 
14.
15.
 
16.
/* 
17.
* Ein Array zur Aufnahme der Dateien 
18.
*/ 
19.
$datei_arr=array(); 
20.
 
21.
/* 
22.
* Die Funktion liest ein Verzeichnis incl. Unterverzeichnisse aus. 
23.
* - $verzeichnis - das soll ausgelesen werden 
24.
* - &$arr - hier wird das Array (s.o.) übergeben. Das & ist eine Referenz auf die Variable, 
25.
* die hier durch direkt von der Funktion verändert wird. 
26.
*/ 
27.
function dir_rekursiv($verzeichnis, &$arr){  
28.
/* 
29.
* Diese Dateitypen sollen eingelesen werden. 
30.
*/ 
31.
 //$datei_typ_arr=array(0 => ".txt", 1 => ".php", 2 => ".htm", 3 => ".html"); 
32.
 $datei_typ_arr=array(0 => ".txt"); 
33.
 $handle = @opendir($verzeichnis);  
34.
 while ($datei =@readdir($handle)){  
35.
  if ($datei != "." && $datei != ".." ){  
36.
   if (is_dir($verzeichnis.$datei)){  
37.
	  dir_rekursiv($verzeichnis.$datei."/", &$arr); 
38.
	 }else
39.
	           /* 
40.
                               * strrchr(string $string, string $zeichen) gibt den Text nach dem letzten Vorkommen von $zeichen incl. $zeichen zurück. 
41.
                              */  
42.
                                $ext=strrchr($verzeichnis.$datei, "."); 
43.
				 /* 
44.
				 * Wenn $ext in dem Dateitypen-Array vorkommt, Datei im Array ablegen. 
45.
				 */ 
46.
				 if(in_array($ext, $datei_typ_arr)){ 
47.
				  $arr[]=$verzeichnis.$datei
48.
49.
				}  
50.
51.
 }  
52.
 @closedir($handle);  
53.
54.
/* 
55.
* Funktionsaufruf mit Verzeichnisangabe und Variable 
56.
*/ 
57.
dir_rekursiv("/www/",$datei_arr); 
58.
 
59.
/* 
60.
* usort($array, Callback-Funktion) sortiert das Array.  
61.
*/ 
62.
usort ($datei_arr, 'cmp'); 
63.
?> 
64.
<!--  
65.
Ein Formular zur Eingabe.  
66.
/--> 
67.
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"
68.
<p>Datei auswählen <select name="seldatei" title="Datei auswählen"></p> 
69.
<option selected value=""> -- Datei auswählen -- </option> 
70.
<?php 
71.
/* 
72.
* Dateinamen in der Selectbox ausgeben. 
73.
*/ 
74.
foreach($datei_arr as $datei){ 
75.
 echo "<option value=\"$datei\">$datei</option>"
76.
77.
?> 
78.
<p></select></p> 
79.
<p>Suchbegriff(e) eingeben  <input type="text" name="suche" title="Geben sie einen oder mehrere Suchbegriff(e) ein"></p> 
80.
<p><input type="submit" name="cmd" value="Suchen" title="Absenden"></p> 
81.
</form> 
82.
<?php 
83.
/* 
84.
* Mit ini_set(PARAMETER) werden Fehler/Hinweise angezeigt. 
85.
*/ 
86.
ini_set('error_reporting', E_ALL|E_STRICT); 
87.
ini_set('display_errors', 'On'); 
88.
/* 
89.
* Parameter der Funktion: 
90.
* - ein oder mehrere Suchbegriffe 
91.
* - einen Dateinamen 
92.
*/ 
93.
function findwort($wort,$textdatei){ 
94.
/* 
95.
* Wenn kein Dateiname eingegeben ist,  Array mit Meldung füllen und beenden. 
96.
*/ 
97.
 if(strlen(trim($textdatei))==0){ 
98.
  $gef_zeilen_arr[]="Wählen sie einen Dateinamen"
99.
  return $gef_zeilen_arr
100.
101.
/* 
102.
* Wenn kein(e) Suchbegriff(e) vorhanden sind,  Array mit Meldung füllen und beenden. 
103.
*/ 
104.
 if(strlen(trim($wort))==0){ 
105.
  $gef_zeilen_arr[]="Geben sie einen oder mehrere Suchbegriff(e) ein"
106.
  return $gef_zeilen_arr
107.
108.
/* 
109.
* Falls ein User (aus Versehen oder "zum Testen") Trennzeichen eingibt wie +, - & usw., 
110.
* werden diese durch ein Komma ersetzt. Die Liste $limiter_arr nach Bedarf erweitern. 
111.
*/ 
112.
$limiter_arr=array(0 => "+", 1 => ";", 2 => "|", 3 => "&", 4 => " "/* Auch Leerzeichen durch Komma ersetzen */, 5 => "-"); 
113.
foreach($limiter_arr as $limiter){ 
114.
 $wort=str_replace($limiter, ",", $wort); 
115.
116.
/* 
117.
* Suchbegriffe in $wort in einem Array ablegen. 
118.
* Enthält $wort nur ein Wort, hat das Array eben nur ein Element. 
119.
*/ 
120.
$wort_arr=explode(",",trim($wort)); 
121.
/* 
122.
* Textdatei zeilenweise in ein Array einlesen. 
123.
* 160 ist die Zeilenlänge, erhöhen falls nötig. 
124.
*/ 
125.
 $text_zeilen_arr=array(); 
126.
 $f = @fopen($textdatei,"r"); 
127.
 /* 
128.
 * Wenn die Textdatei nicht geöffnet werden konnte (z.B. fehlende Rechte), Array mit Meldung füllen und beenden. 
129.
 */ 
130.
 if(!$f){ 
131.
  $gef_zeilen_arr[]="Datei: ".$textdatei
132.
  $gef_zeilen_arr[]="Die Datei ".$textdatei." konnte nicht geöffnet werden"
133.
	return $gef_zeilen_arr
134.
135.
 while($zeile=@fgets($f,160)){ 
136.
  $text_zeilen_arr[]=$zeile
137.
138.
 @fclose($f); 
139.
/* 
140.
* Zeilenweise das Array mit der Funktion strpos durchsuchen. 
141.
* strpos arbeitet case-sensitiv, deshalb werden mit strtolower 
142.
* alle Groß- in Kleinbuchstaben umgewandelt. 
143.
*/ 
144.
 $gef_zeilen_arr=array(); 
145.
 $gef_zeilen_arr[]="Datei: ".$textdatei
146.
 $i=0; 
147.
 while($i<count($text_zeilen_arr)){//while
148.
  $k=0; 
149.
	/* 
150.
	* In der inneren Schleife wird nun Wort für Wort geprüft, ob es in der Textzeile vorkommt. 
151.
	*/ 
152.
	while($k<count($wort_arr)){//while
153.
   $pos = @strpos(strtolower($text_zeilen_arr[$i]),strtolower($wort_arr[$k])); 
154.
	 /* 
155.
	 * Bitte den Operator "===" beachten. 
156.
	 */ 
157.
	 if($pos === false){ 
158.
	  /* 
159.
	  * Wenn strpos das boolsche FALSE zurückgibt, passiert nichts. 
160.
		*/ 
161.
		}else
162.
	 			 /* 
163.
				 * Ansonsten die Array-Zeile mit einer Meldung füllen. 
164.
				 * - ($i+1) - Da ein Array bei 0 beginnt, wird eine 1 aufaddiert, weil sonst die falsche Zeilennummer am Bildschirm ausgegeben würde. 
165.
				 * - ($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. 
166.
				 */ 
167.
				 $gef_zeilen_arr[]="Der Suchbegriff ".$wort_arr[$k]." wurde in Zeile ".($i+1)." an Position ".($pos+1)." gefunden ==> ".$text_zeilen_arr[$i]; 
168.
169.
	 $k++; 
170.
	}//end while
171.
  $i++; 
172.
 }//end while
173.
 /* 
174.
 * Enthält das Array mind. 2 Elemente(den Dateinamen und eine oder mehr gefundene Textzeilen), so wird das Array zurückgegeben. 
175.
 * Ansonsten wird das Array mit einer Meldung gefüllt und zurückgegeben. 
176.
 */ 
177.
 if(count($gef_zeilen_arr)>1){ 
178.
  return $gef_zeilen_arr
179.
 }else
180.
 			 $gef_zeilen_arr[]="Der/die Suchbegriff(e) \"$wort\" wurde(n) nicht gefunden"
181.
			 return $gef_zeilen_arr
182.
183.
184.
/* 
185.
* Ist das Formular gesendet, gibt die Funktion ein Array zurück, deshalb mit foreach ausgeben. 
186.
*/ 
187.
if(isset($_POST['suche'])){ 
188.
 $erg_arr=findwort($_POST['suche'],$_POST['seldatei']); 
189.
 foreach($erg_arr as $erg){ 
190.
  /* 
191.
	* Die gefundenen Textzeilen mit der Funktion htmlspecialchars ausgeben, falls die durchsuchte Textdatei 
192.
	* eine HTML/PHP - oder ähnliche Datei ist.  
193.
	*/ 
194.
  echo "<pre>".htmlspecialchars($erg)."</pre>"
195.
196.
197.
?> 
198.
</body> 
199.
</html>

. . . und End' is'.


Gruß
Günni
Mitglied: TsukiSan
28.05.2011 um 17:20 Uhr
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:
01.
SuchText = LCase("Im vbarchiv gibt es jede Menge Tipps und jede Menge Infos.") 
02.
SuchZeichen = LCase("gibt") 
03.
  
04.
for i = 1 to len(Suchtext) 
05.
	temp = mid(Suchtext,i,Len(SuchZeichen)) 
06.
	if temp = SuchZeichen then temp1 = temp1 & i & vbcrlf 
07.
next 
08.
 
09.
msgbox temp1
Mich persönlich erschlägt der Code etwas. Aber eventuell liegt es daran, dass ich von PHP keine Ahnung habe.

Viele Grüße
Tsuki
Bitte warten ..
Mitglied: Guenni
29.05.2011 um 09:52 Uhr
Hi TsukiSan,

danke für dein Feedback. Auch in meinem Script ist der eigentliche Suchvorgang nur ein paar Zeilen lang,

nimmt man die Kommentarzeilen mal raus . . .

01.
<?php 
02.
$i=0; 
03.
 while($i<count($text_zeilen_arr)){//while
04.
  $k=0; 
05.
	/* 
06.
	* In der inneren Schleife wird nun Wort für Wort geprüft, ob es in der Textzeile vorkommt. 
07.
	*/ 
08.
	while($k<count($wort_arr)){//while
09.
   $pos = @strpos(strtolower($text_zeilen_arr[$i]),strtolower($wort_arr[$k])); 
10.
	 /* 
11.
	 * Bitte den Operator "===" beachten. 
12.
	 */ 
13.
	 if($pos === false){ 
14.
	  /* 
15.
	  * Wenn strpos das boolsche FALSE zurückgibt, passiert nichts. 
16.
		*/ 
17.
		}else
18.
	 			 /* 
19.
				 * Ansonsten die Array-Zeile mit einer Meldung füllen. 
20.
				 * - ($i+1) - Da ein Array bei 0 beginnt, wird eine 1 aufaddiert, weil sonst die falsche Zeilennummer am Bildschirm ausgegeben würde. 
21.
				 * - ($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. 
22.
				 */ 
23.
				 $gef_zeilen_arr[]="Der Suchbegriff ".$wort_arr[$k]." wurde in Zeile ".($i+1)." an Position ".($pos+1)." gefunden ==> ".$text_zeilen_arr[$i]; 
24.
25.
	 $k++; 
26.
	}//end while
27.
  $i++; 
28.
 }//end while
29.
?>
Der Grund für die zwei while-Schleifen ist der, dass man mehrere Suchbegriffe eingeben kann, und jede Textzeile nach diesen Begriffen durchsucht wird. Die Suche nach

"vb tipp info" in der Zeile "Im vbarchiv gibt es jede Menge Tipps und jede Menge Infos." z.B. hätte dann zur Folge, dass diese Zeile zusammen mit einem der Suchbegriffe

dreimal ausgegeben wird. Das Script liest außerdem ein Verzeichnis samt Unterverzeichnisse aus, sortiert die Dateinamen und stellt diese in einer select-Box zur Auswahl dar,

damit man den Dateinamen nicht eintippen muß. Der Rest sind halt Fehlerbehandlung etc.. Ich wollte halt nicht nur die Funktion strpos erklären, das kann man selber hier

http://de2.php.net/manual/de/function.strpos.php nachlesen, sondern eine Anwendung vorstellen, die auch zur Inspiration dienen kann. Man könnte z.B. dieses Script so umschreiben,

dass die Seiten eines Projekts durchsucht werden, um dann, statt die gef. Zeilen auszugeben, z.B. eine Linkliste auf Projektseiten zu generieren.

Danke auch für dein "hilfreich".


Gruß, schönen Sonntag

Günni
Bitte warten ..
Mitglied: Guenni
05.06.2011 um 19:14 Uhr
Hallo!

Änderungen im Script.

Im Dateitypenarray die Dateiendungen mit Punkt angeben.

Zeile 31:
$datei_typ_arr=array(0 => ".txt", 1 => ".php", 2 => ".htm", 3 => ".html");


Statt strpos wird nun strrchr verwendet. strpos(string $string, -3) findet

so nur die letzten 3 Zeichen, bei der Endung html also nur tml.

ab Zeile 40:
/*
  • strrchr(string $string, string $zeichen) gibt den Text nach dem letzten Vorkommen von $zeichen incl. $zeichen zurück.
*/
$ext=strrchr($verzeichnis.$datei, ".");

Gruß
Günni
Bitte warten ..
Ähnliche Inhalte
PHP

PHP RFC: Mcrypt Extension wird ab PHP 7.2 entfernt

Information von FrankPHP

Ein RFC ist grob eine Abstimmung unter den PHP-Entwicklern, um neue, bestehende oder alte Feature hinzuzufügen, zu ändern, oder ...

PHP

PHP 7.2 veröffentlicht

Information von FrankPHP

Das PHP-Team hat heute, den 30.11.207 die aktuelle Version von PHP 7.2 veröffentlicht. Eine der wichtigsten Änderungen für PHP-Entwickler ...

Administrator.de Feedback

Entwicklertagebuch: PHP 7

Information von admtechAdministrator.de Feedback4 Kommentare

Hallo Administrator User, mit dem heutigen Tag haben wir unsere Server komplett auf die PHP Version 7 umgestellt. Wir ...

PHP

Endlich: PHP bekommt eine offizielle Spezifikation

Information von FrankPHP

Dank Facebook bekommt die Programmiersprache PHP nach über 20 Jahren endlich eine offizielle Spezifikation. Facebook und die PHP-Community arbeiten ...

Neue Wissensbeiträge
CPU, RAM, Mainboards
Neverending story
Tipp von keine-ahnung vor 19 StundenCPU, RAM, Mainboards1 Kommentar

Da kommt man mit dem fixen gar nicht mehr hinterher und die CPU erreichen wieder Rechenleistungen im Bereich des ...

Multimedia & Zubehör
AVM Fritz USB WLAN Sticks schneller einschalten
Tipp von NetzwerkDude vor 2 TagenMultimedia & Zubehör4 Kommentare

Die AVM Fritz WLAN Sticks haben in der Firmware 2 Modis: Einmal als Massenspeicher und einmal als WLAN Netzwerkkarte ...

Windows Server

Windows Server Backup schlägt fehl - Lösung 2008-2016

Tipp von BiGnoob vor 2 TagenWindows Server

Hi zusammen , ich möchte gerne einen Lösungstipp abgeben für folgenden Fehler: Lösung ist folgende:

Humor (lol)
Telekom vs. O2 - 3:2
Erfahrungsbericht von the-buccaneer vor 3 TagenHumor (lol)4 Kommentare

Unglaublich aber wahr: Nachdem mein privater Anschluss am 19.04.18 auf VOIP und VDSL umgestellt wurde, hatte ich seitdem 1,5 ...

Heiß diskutierte Inhalte
PHP
Nach Umzug zu 1und1 bekomme ich beim Eintrag in die DB Tabelle folgenden Fehler
gelöst Frage von jensgebkenPHP35 Kommentare

INSERT command denied to user 'dbo45342345342231244'@'112.127.102.073' for table 'orders'

Rechtliche Fragen
DSGVO - Impressum und Datenschutz auf Anmeldeseiten notwendig?
Frage von StefanKittelRechtliche Fragen16 Kommentare

Hallo, was mit gerade eingefallen ist. Muss man auf Anmeldeseiten auch ein Impressum und Datenschutzhinweis haben? Auch hier wird ...

Windows Userverwaltung
Problem mit Benutzerprofil
Frage von lieferscheinWindows Userverwaltung12 Kommentare

Guten Tag liebe Community, folgendes Problem habe ich: User meldet sich auf Client A an - sein Homelaufwerk verbindet. ...

Windows Server
2003er RDS Server lässt alten ThinClient nach Updates nicht mehr anmelden
Frage von KnorkatorWindows Server9 Kommentare

Hallo zusammen, wir hatten die Aufgabe, ein System (keine Domänenanbindung) zu virtualisieren welches mehrere Jahre keine Updates gesehen hat. ...