String splitten

S

sevY

Hi,

ich möchte folgendes.

PHP:
$string='Das ist ein Satz. Das ist der Satz mit dem Suchwort LALA. Das ist noch ein Satz';

//Gib mir $string aus, aber nur den Satz, der das Suchwort 'LALA' enthält.

Also muss im Prinzip der String auf das Suchwort geprüft werden und dann vom Suchwort ausgehen am Punkt (.) danach und nach dem Punkt (.) davor abgeschnitten werden.

Liebe Grüße

Yves
 
Am einfachsten wäre da wohl eine Konstruktion über REGEXP (reguläre Ausdrücke). Aber ich vermute es wird eine hässliche Konstruktion ;)

Horror
 
$aSaetze = explode(".", $string);

Nun jedes Element von $aSaetze testen. Fertig.
 
Moin, moin!

Wie Horror schon sagte sind Reguläre Ausdrücke hier das eleganteste.

Zum Beispiel so:
PHP:
<?php

$string = 'Das ist ein Satz. Das ist der Satz mit dem Suchwort LALA. Das ist noch ein Satz';

$pattern = "/(?:\w|\s)+LALA(?:\w|\s)*\./";
if(preg_match($pattern, $string, $match) > 0)
{
  echo $match[0] . "\n";
}

?>

Bis neulich ...
 
H,

vielen Dank! Der Lösungansatz ist genau das, was ich brauche. Aber leider funktioniert das in meiner Funktion nicht. Es wird entweder kein Ergebniss, oder immer nur ein Ergebnis ausgegeben.

Hier die function.inc.php

PHP:
<?php
//Verzeichnis wird auf definierte Dateien gescannt

function scanFiles($path,$key,$type)
    {
    $handle=opendir($path);
    $i=0;
    while($file=readdir($handle))
        {
        if($file!='.' && $file!='..' && preg_match('/.'.$type.'/i',$file))
            {
            if(preg_match('/'.$key.'/i',strip(readContent($path,$file))))
                {
//Suchwort wird markiert und ein Href wird konkateniert, welcher in einem Array returned wird.
                $result[$i]='<a href="'.$file.'" target="_self">'.eregi_replace($key,'<b>'.strtoUpper($key).'</b>',strip(readContent($path,$file))).'</a>';
                $i++;
               
                /*
                preg_match('/(?:\w|\s)+'.strtoupper($key).'(?:\w|\s)*\./', strip(readContent($path,$file)), $match);
                $result[$i]='<a href="'.$file.'" target="_self">'.eregi_replace($key,'<b>'.strtoUpper($key).'</b>',$match[0]).'</a>';
                $i++;            */
                }
            }
        }
    return $result;
    closedir($handle);
    }

//Datei wird ausgelesen
function readContent($path,$file)
    {
    $binaries=fopen($path.$file,'rb');
    $scan=fread($binaries,filesize($path.$file));
    return $scan;
    }
    
//Plain Text erzeugen
function strip($content)
    {
    $content=preg_replace('/(\<script)(.*?)(script>)/si','',$content);
    $content=strip_tags($content);
    $content=str_replace('<!--','&lt;!--',$content);
    $content=preg_replace('/(\<)(.*?)(--\>)/mi',''.nl2br('\\2').'',$content);
    return $content;
    }
?>


Und so binde ich das ein…

PHP:
            if(isset($_POST['operation']))
                {
                echo'
                    <span class=ttl>
                        <b>Suchergebnisse</b>
                    </span>
                    ';
                if(strlen($_POST['key'])>=3)
                    {
                    $return=scanFiles(getcwd().'/',$_POST['key'],'shtml');
                    if(!empty($return))
                        {
                        foreach($return as $result)
                            {
                            echo '<p>'.$result.'</p>';
                            }
                        }
                    else
                        {
                        echo'<p>Die Suche nach <b>'.strtoupper($_POST['key']).'</b> ergab keine Ergebnisse.</p>';
                        }
                    }
                else
                    {
                    echo'<p>Das Suchwort mu&szlig; mindestens 3 Zeichen lang sein.</p>';
                    }                   
                }

Hat jemand eine Idee?

Liebe Grüße

Yves
 
Was steht denn in $key und woher kommt der Wert?
Wenn in Key nur das zu suchende Wort steht macht nämlich "preg_match('/'.$key.'/i',..." nicht viel Sinn, da Du ja den ganzen zugehörigen Satz haben wolltest, oder doch nicht?!
Was genau willst Du haben? Von mehrere Vorkommen o.ä. war in Deinem ersten Posting nicht die Rede.

Bis neulich ...
 
Das ist genau der Grund warum ich weitestgehend einen Bogen um regex mache. Die Lösung von aguilera mag die manuelle Variante sein. Sie ist jedoch eingängiger und leichter wartbar, da man sie auch nach Monaten noch sofort versteht! Regex verwende ich nur, wenn nichts anderes mehr hilft.
 
wegus schrieb:
Das ist genau der Grund warum ich weitestgehend einen Bogen um regex mache.
Hä? Was ist "genau der Grund"?

wegus schrieb:
Die Lösung von aguilera mag die manuelle Variante sein. Sie ist jedoch eingängiger und leichter wartbar, ...
Soso. IST sie das oder empfindest DU sie als einfacher?
Im Übrigen dürfte diese Variante um ein vielfaches langsamer sein.

wegus schrieb:
... da man sie auch nach Monaten noch sofort versteht!
Und warum sollte das bei RegExpr nicht der Fall sein? Vorausgesetzt man arbeitet regelmäßig mit RegExpr.

wegus schrieb:
Regex verwende ich nur, wenn nichts anderes mehr hilft.
Ist ja auch in Ordnung. Ich selber nutze es aber bei jeder passenden Gelegenheit. Immer wenn ich irgendetwas mit Stringbearbeitung zu tun hab kommt RegExpr ins Spiel.
Auch in Fällen wo ein einfaches substr() o.ä. genauso funktionieren würde nehme ich aus Geschwindigkeitsgründen immer gerne RegExpr.

Bis neulich ...
 
@Gibberish:
Nun mal nicht so empfindlich! Ich arbeite täglich mit PHP ( seit Version 3.04 vor fünf Jahren). Habe demzufolge auch fünf Jahre alte Skripte von unterschiedlichen Programmierern hier. Regex ist eben nicht leicht lesbar,
auch für alte Perl-Hasen nicht und ich kann auch perl! Das mit der Rechenzeit relativiert sich mit der Rechenleistung der Server und scheint mir eher akademisch zu sein! Du darfst es ja gerne anders sehen und nat. gibt es Fälle wo nur regex Sinn macht. Ich persönlich zähle den obigen genau nicht dazu,
aber das ist meine persönliche Meinung

Gruß Karsten
 
wegus schrieb:
@Gibberish:
Nun mal nicht so empfindlich!
Doch. Auf "DAS IST so weil ICH soundso arbeite" reagiere ich immer empfindlich.
Wenn jemand sagt "Ich empfinde Lösung XY als eleganter" hab ich kein Problem damit aber zu sagen "Lösung XY ist eleganter" und dann nichtmal eine Begründung mitzuliefern kann ich nicht ab.

wegus schrieb:
Regex ist eben nicht leicht lesbar,
AHH.. Da ist wieder dieses IST! Du findest RegEx nicht leicht lesbar aber deswegen IST es das noch lange nicht.
Außerdem hängt das immer stark vom Anwendungsfall ab und eine RegEx, die das hier genannte Problem behandelt, halte ich sehr wohl für leicht lesbar. Und da wo RegEx wirklich unleserlich werden käme man mit explode() oder anderen stringfunktionen ohnehin kaum weiter.

wegus schrieb:
Das mit der Rechenzeit relativiert sich mit der Rechenleistung der Server und scheint mir eher akademisch zu sein!
Aha.. anstatt die Software zu optimieren/beschleunigen kaufe ich also lieber neue Hardware. Und nein es ist nicht akademisch und das solltest Du mit 5 Jahren Erfahrung eigentlich wissen.
Natürlich merkt man bei 1000 Wörtern keinen Unterschied aber bei mehreren hundert MB Text ändert sich die Laufzeit schon ganz gewaltig.

wegus schrieb:
Du darfst es ja gerne anders sehen
danke zu gnädig. :)

wegus schrieb:
und nat. gibt es Fälle wo nur regex Sinn macht. Ich persönlich zähle den obigen genau nicht dazu,
Wobei der o.g. Fall nicht ausreichend spezifiziert ist.
Guck Dir z.B. mal den Speicherbedarf an, wenn Du über 100MB Text ein explode(".", ... machst und tausende von Strings in ein Array geballert werden um diese hinterher alle wieder zu durchlaufen. Bei 3-4 Sätzen ist das ganze natürlich kein Problem.

Bis neulich ...
 
Doch. Auf "DAS IST so weil ICH soundso arbeite" reagiere ich immer empfindlich.

Womit Du ja auch recht hast!


Aha.. anstatt die Software zu optimieren/beschleunigen kaufe ich also lieber neue Hardware. Und nein es ist nicht akademisch und das solltest Du mit 5 Jahren Erfahrung eigentlich wissen.

Nun ja es sind über 20 Jahre, mein erster UNIX Rechner hatte eine 10MHz 68000er CPU! Ich habe es akademisch genannt, weil in realitas selten die Zeit da ist jeden Code vollständig zu optimieren. Es ist meist in der Tat günstiger das via Hardware aufzufangen. Mein Webserver für 50 User ist ein HP-LH3 ( Ein Pentium III mit 500 MHz) und das Ding reicht wunderbar um darauf via Intranet einen Großhandel zu betreiben mit konkurrierenden Anfragen im Millisekundenbereich (extremum). Von der Entwurfsseite hast Du recht. Was Datenbankabfragen angeht weiche ich davon auch kein Stück ab. Beim reinen Softwareentwurf muß ich dabei aber derartige Abwägungen treffen. Da ist dann aus meiner Sicht ( und Du hast recht das ist subjektiv) ein schnell zu lesender Code der gut kommentiert ist der Bessere. Es mag Codierungen geben die effizienter sind. Aber die TCO ( wenn Du so willst) rechnet sich nicht. Viele Programmierer haben Schwierigkeiten mit regex und Du hast nat. Recht mit Deiner Vermutung, daß auch ich erst nachlesen muß. Meine Erfahrung ist aber eben, daß ich damit einer Majorität angehöre. Und für die, in meinem Umfeld, plane ich. Mir ist bewußt das das nicht für alle gilt. Solch eine pauschale Aussage würde ich daher auch nicht treffen. Da Du meine Formulierung so auffaßt, war diese ergo falsch. Ich hoffe das damit klargestellt zu haben.

Ich bin auch kein freund gut zusammengekürzter Perl-Scripte oder C-Programme. Für Optimierungen hat man Compiler oder gute Interpreter. Allein bei PHP ist da die Effektivität durch die neue Zend-Engine so gestiegen, daß ich mir da untergeordnete Sorgen mache. Ich verwende PHP auch als reine Scriptsprache für administrative Dinge und bewege durchaus große Mengen Texte und Daten. Sollte ich da jede Zeile bis ins letzte ausformulieren, wäre ich sicher arbeitslos oder würde für eine Verwaltung arbeiten müssen ( da hat man ja meist mehr Zeit). Ich wage auch zu behaupten, daß ich mit dem Problem nicht allein dastehe. Das das ausschließlich so wäre würde ich aber nicht behaupten wollen.

und nun laß uns die Haarspalterei beenden ;-)

regex sind nicht böse und arrays unter PHP sind langsam
 
Gibberish schrieb:
Was steht denn in $key und woher kommt der Wert?
Wenn in Key nur das zu suchende Wort steht macht nämlich "preg_match('/'.$key.'/i',..." nicht viel Sinn, da Du ja den ganzen zugehörigen Satz haben wolltest, oder doch nicht?!

Moin.

$key ist ein Funktionsparameter der Funktion scanFiles(), welches mittels POST aus dem Suchformular als Suchwort übermittelt wird. Die von dir zitierte Stelle trifft nur erstmal eine Vorauswahl aus ca. 100 HTML Dokumenten, die gescannt werden. Da ist es nur wichtig, das dort das Keyword enthalten ist.
In der bedingten Anweisung erfolgt dann die Konkatenation der Ergebnisse zu einem href Anchor, weswegen die Files erneut gescannt werden.
Ich glaube, hier ist auch das Problem.
Ich bekomme bei einigen Suchwörtern als Rückgabe 10 Ergebnisse mit RegExp, wie auch ohne… nur das mit RegExp teilweise keine Sätze zurückgegeben werden (=0).
Es wird also ein href anchor konkateniert, falls das Suchwort enthalten ist, jedoch erst auch der beschreibende Teil des anchors, wenn das Suchwort in einem Satz enthalten ist.

Ich hab nun provisorisch erstmal explode genommen, was jedoch sehr unschön ist, da ich dann bei Massentexten oft nur einen unbedeutenden Satz ohne das Suchwort bekomme.


Yves
 
Unabhängig von der Glaubensfrage (regex,explode), müssen beide Wege immer Ergebnisse liefern und dann auch nur mit dem Suchtext im Satz, sonst liegt da ja schon der erste Fehler.

wie sieht denn vor if (!empty()) das array $return aus? Sprich wie sieht ein
print_r($return);
aus?

btw: closedir muss vor return $result stehen, auch wenn es das Problem nicht löst.
 
Hi,

so sieht zb die Suchrückgabe nach einem Begriff wie SRM aus.

Code:
//html rendered
.

.

ftsprozesse in Ihrem PIM oder Ihrer Procurementumgebung..

.

.

.

.

.

.

.

Der Punkt kommt daher, das ich diese in den String konkateniert habe, falls die Funktion zum Auslesen des Satzes 0 zurückgibt und also nicht übereinstimmt.


So sieht dabei der Scanfiles() Teil aus

PHP:
function scanFiles($path,$key,$type)
    {
    $handle=opendir($path);
    $i=0;
    while($file=readdir($handle))
        {
        if($file!='.' && $file!='..' && preg_match('/.'.$type.'/i',$file))
            {
            if(preg_match('/'.$key.'/i',strip(readContent($path,$file))))
                {
                $pattern='/(?:\w|\s)+'.$key.'(?:\w|\s)*\./i';
                $string=strip(readContent($path,$file));
                preg_match($pattern, $string, $match);
                $result[$i]='<a href="'.$file.'" target="_self">'.$match[0].'.</a>';
                $i++;
                }
            }
        }
    closedir($handle);
    return $result;    
    }


Die Rückgabe des Gesamtergebnisses, welches ein Array ist, ergibt, falls er nicht mit foreach() ausgelesen wird

Code:
Array

War es das was du wissen wolltest?


Nun… ich habe mir nocheinmal Gedanken gemacht.

Das Problem liegt ausformuliert darin, das wenn ein Suchwort in einem Massentext vorkommt, dieses noch längst nicht in einem syntaktischen Satzgefüge, von einem Punkt abgetrennt, vorkommen muss.

Jedoch ist das erste Kriterium, also das das Suchwort überhaupt vorkommt, das ausschlaggebende bei der Suche. Das Kriterium „Wort innerhalb des Satzes“ dient ja nicht im eigentlichen Sinne als Auswahlkriterium einer semantisch-orientierten Suche, sondern eher dem Zweck der Extraktion eines Fragments zur besseren Weiterverarbeitung im Layout.

Daher würde ich auch folgendes sehr begrüßen, falls es klappt…

Es soll, vom ersten Vorkommen des Suchwortes innerhalb des Textes 4 Wörter davor und 4 Wörter danach ausgegeben werden.
Kriterium für ein neues Wort ist ein Leerzeichen.
Falls 4 Wörter davor oder danach am Ende bzw. am Anfang nicht möglich sind, einfach den Anfang oder das reguläre Ende nehmen.
Falls 4 Wörter möglich sind mit ... davor und danach abkürzen… es sei denn, es befindet sich direkt davor oder danach ein Punkt…

Ich dachte erst an Substr()… aber das würde unschön Wörter abschneiden… ich denke auch regex ist hier gefragt… nur bin ich da auf eure Hilfe angewiesen.

Like this…
PHP:
$string='Das ist ein Satz. Das ist der Satz mit dem Suchwort LALA. Das ist noch ein Satz'; 

echo gesuchteFunktion($string);

//Satz mit dem Suchwort LALA. Das ist noch ein Satz.

//Bzw


$string='Das ist ein Satz. Das ist der Satz blubb bla bla mit dem Suchwort LALA. Das ist so.'; 

echo gesuchteFunktion($string);

//....bla mit dem Suchwort LALA. Das ist so.

Nebenbei gefragt… was passiert, wenn in einem Satz dann 3 mal das Suchwort aufeinander trifft? Oder greift da das Beenden von preg_match() nach dem ersten Treffer im Gegensatz zu preg_match_all() ?


Liebe Grüße

Yves
 
Zunächst mal das banale: scanFiles ist fehlerhaft wie man sieht.

Dann ein Tipp: print_r($array); kann man im Quelltext der Seite super lesen,
der HTML-output ist unnötig.

Zur Problemlösung:
Viele einfache Schritte sind der bessere Weg:
if($file!='.' && $file!='..' && preg_match('/.'.$type.'/i',$file)
Hier reduziert sich doch alles auf die letzte Bedingung, Du kannst also einfach
schreiben:
if (preg_match('/.'.$type.'/i',$file)<1) // Kommt 0-mal vor
continue; // Also nächste Datei nehmen

den Fehler vermute ich ( mehr Zeit habe ich nicht) in der Zeile:
if(preg_match('/'.$key.'/i',strip(readContent($path,$file))))

die gibt immer einen Wert zurück der ergo auch existiert, selbst wenn es 0 ist. Ich würde

if(preg_match('/'.$key.'/i',strip(readContent($path,$file)))>0)

verwenden. Das ist jedoch geraten mangels Zeit.


Was Deine Idee mit den Worten angeht kannst Du Dir ja auch per strpos die Position des Strings in der datei ausgeben lassen. Gehst pauschal x Zeichen zurück und nach vorn und trennst das Fragment heraus (Bound-Checking)
Dann suchst Du Dir mittels String-Funktionen in diesem Fragment das Erste und das letzte Leerzeichen, bildest aus dem Substring einen Weiteren und fertig. Dabei kannst Du genau so nat. auch auf Interpunktionen testen.
 
Hi.
wegus schrieb:
Zunächst mal das banale: scanFiles ist fehlerhaft wie man sieht.
Das würde ich nicht so pauschal und undifferenziert sagen ;)

wegus schrieb:
Dann ein Tipp: print_r($array); kann man im Quelltext der Seite super lesen,
der HTML-output ist unnötig.
Mir erschliesst sich hier der Sinn nicht… ich sehe doch auch so welche Indices nicht gefüllt werden.

Aber ok, die Ausgabe liefert zb das:

Code:
Array (  
[0] => 1.)*  Die Applikation ist komplett in Java implementiert und basiert auf den neuesten Technologien.  
[1] => 2.)* xxxxx begannen xxxx und xxxx mit der Entwicklung von xxxx auf Basis von Java und XML.  
[2] => 3.)*  
[3] => 4.)* in Java entwickelte Webapplikation.  
[4] => 5.)* )

wegus schrieb:
Zur Problemlösung:
Viele einfache Schritte sind der bessere Weg:
if($file!='.' && $file!='..' && preg_match('/.'.$type.'/i',$file)
Hier reduziert sich doch alles auf die letzte Bedingung, Du kannst also einfach
schreiben:
if (preg_match('/.'.$type.'/i',$file)<1) // Kommt 0-mal vor
continue; // Also nächste Datei nehmen
Ok, da stimme ich dir zu. Habe ich auch angepasst.

wegus schrieb:
den Fehler vermute ich ( mehr Zeit habe ich nicht) in der Zeile:
if(preg_match('/'.$key.'/i',strip(readContent($path,$file))))

die gibt immer einen Wert zurück der ergo auch existiert, selbst wenn es 0 ist. Ich würde

if(preg_match('/'.$key.'/i',strip(readContent($path,$file)))>0)

verwenden. Das ist jedoch geraten mangels Zeit.
Das schafft auch keine Abhilfe. Aber du hast da ebenfalls recht. Ich war der Annahme, das preg_match() rein boolsch ist. Ein Blick auf de.php.net sorgte aber für Klarheit.

wegus schrieb:
Was Deine Idee mit den Worten angeht kannst Du Dir ja auch per strpos die Position des Strings in der datei ausgeben lassen. Gehst pauschal x Zeichen zurück und nach vorn …

Ok, das habe ich mal ausprobiert.

PHP:
function scanFiles($path,$key,$type,$length,$limit)
    {
    if(strlen($key)>=$limit)
        {
        $handle=opendir($path);
        $i=0;
        while($file=readdir($handle))
            {
            if(preg_match('/.'.$type.'/i',$file)>0)
                {
                $stuff=strip(readContent($path,$file));
                if(preg_match('/'.$key.'/i',$stuff)>0)
                    {
                    $offset=strpos(strtoupper($stuff),strtoupper($key));
                    $marked=eregi_replace($key,'<b>'.strtoUpper($key).'</b>',$stuff);
                    $result[$i]='<a href="'.$file.'" target="_self">'.($i+1).'.)&nbsp;(...)&nbsp;'.substr($marked,($offset-($length/2)),$length).'(...)</a>';
                    $i++;
                    }
                }
            }
        closedir($handle);
        return $result; 
        }
    else
        {
        return false;
        }   
    }

wegus schrieb:
und trennst das Fragment heraus (Bound-Checking)
Genauere Erklärung zur Umsetzung bitte :)
wegus schrieb:
Dann suchst Du Dir mittels String-Funktionen in diesem Fragment das Erste und das letzte Leerzeichen, bildest aus dem Substring einen Weiteren und fertig. Dabei kannst Du genau so nat. auch auf Interpunktionen testen.

Wenn du mehr Zeit hast, könntest du mal n Snip posten?

Yves
 
Hallo Yves,

mit Boundchecking meinte ich schlicht zu prüfen ob der Startpunkt nicht negativ wird und ob der Endpunkt auch nicht hinter dem String liegt.

Angenommen du hast jetzt so einen $string der Deinen Suchtext enthält, sowie z.B. 20 Zeichen davor und 20 Zeichen danach. Dann erhältst Du das erste Leerzeichen mit:

$first_blank=strpos ( $string, " ");

Analog bekommst Du das letzte Zeichen so:

$last_blank=strrpos ( $string, " ");
$length=strlen($string); // Wir merken uns die Gesamtlänge
// und trennen den Substring nach dem Leerzeichen heraus
// Hinten schneiden wir gleichzeitig alles bis zum letzten Blank weg:
$cutted=substr($string,$first_blank+1,-($length-$last_blank));

Wenn Du magst kannst Du dann genau so auch Interpunktion entfernen.

Ein Problem sehe ich übrigens noch bei den Zeilentrennern! Ich weiß ja nicht wie Du die Dateien einliest, aber Du bist sicher, daß die Zeilenumbrüche nicht mehr in Deinem String sind ja ?


Was die Geschichte mit booleschen Ergebnissen angeht, das ist in PHP nach wie vor kritisch. Gaaanz früher gab es kein true und false. Da war 0==false und 1==true. Das wurde später geändert und zieht in einigen Dingen bis heute Fäden. Ich schaue daher immer zuerst nach solchen Fehlerquellen. Aus den gleichen Gründen benutze ich auch kein is_integer
oder ähnliches. Die haben früher schlicht nicht zuverlässig gearbeitet und ich habe mir mit der Zeit eine eigene Bibliothek (ähnlich pear nur viel spezieller und nat. kleiner) an Funktionen und Classes erzeugt. Generell gilt, trau keiner PHP Fehlermeldung und im Notfall alles per print/print_r kontrollieren...

Ich hoffe das reicht um Deinen Indexübersicht zu erstellen

Gruß Karsten
 
Zuletzt bearbeitet:
wegus schrieb:
mit Boundchecking meinte ich schlicht zu prüfen ob der Startpunkt nicht negativ wird und ob der Endpunkt auch nicht hinter dem String liegt.
Das ist zwar sauberer, aber meines Erachtens nicht notwendig, da PHP automatisch bei solchen Werten einen Fallback auf das die erste bzw. letzte Stelle macht.
Teste mal.
PHP:
<?php
$string='123456789';
$offset=strpos($string,'5');
$length=strlen($string);
$overdosed=substr($string,$offset-1000,$length+1000);
echo $overdosed;
?>

wegus schrieb:
Angenommen du hast jetzt so einen $string der Deinen Suchtext enthält, sowie z.B. 20 Zeichen davor und 20 Zeichen danach. Dann erhältst Du das erste Leerzeichen mit:

$first_blank=strpos ( $string, " ");

Analog bekommst Du das letzte Zeichen so:

$last_blank=strrpos ( $string, " ");

PHP:
$string=' 123456789 ';
$first=strpos($string,' ');
$last=strpos($string,' ');
echo $first.$last;

Ergibt 00!

wegus schrieb:
Ein Problem sehe ich übrigens noch bei den Zeilentrennern! Ich weiß ja nicht wie Du die Dateien einliest, aber Du bist sicher, daß die Zeilenumbrüche nicht mehr in Deinem String sind ja ?
Ich hoffe schon.
Die Daten kommen aus .shtml Dateien, die ich binary einlese.
PHP:
function readContent($path,$file)
    {
    $binaries=fopen($path.$file,'rb');
    $scan=fread($binaries,filesize($path.$file));
    return $scan;
    }

Damit strippe ich das ganze… eventuell verfälschen \r\n usw. das Ergebnis, oder?

PHP:
function strip($content)
    {
    $content=preg_replace('/(\<script)(.*?)(script>)/si','',$content);
    $content=strip_tags($content);
    $content=str_replace('<!--','&lt;!--',$content);
    $content=preg_replace('/(\<)(.*?)(--\>)/mi',''.nl2br('\\2').'',$content);
    return $content;
    }

Hier mal ein etwas überarbeitete Funktion… hier übergebe ich der Einfachheit als Parameter die minimal geforderte Länge des Suchergebnisses und ein Limit, welches die Länge des beschreibenden Teil des href Anchor definiert. Aufgrund des Fallbacks bei substr() ist ja ein Bounding Check nicht notwendig… könnte man aber noch mit if(strlen($string<=$limit) überprüfen und dann gebenenfalls $limit = strlen($string); setzen.
Vorher hatte ich das so, das ich mit strpos() das Suchwort im String lokalisiert habe und diesen Offset mit $limit/2 und $limit in substr() gesetzt habe. Häßlich war da eben nur das Abschneiden der teilweise ersten Wörter, daher bin ich dann doch auf die u.a. Methode zurückgekommen.
Aber ich bastel weiter.
PHP:
function scanFiles($path,$key,$type,$length,$limit)
    {
    if(strlen($key)>=$limit)
        {
        $handle=opendir($path);
        $i=0;
        while($file=readdir($handle))
            {
            if(preg_match('/.'.$type.'/i',$file)>0)
                {
                $stuff=strip(readContent($path,$file));
                if(preg_match('/'.$key.'/i',$stuff)>0)
                    {
                    $result[$i]='<a href="'.$file.'" target="_self">'.($i+1).'.)&nbsp;'.substr($stuff,0,$length).'(...)</a>';
                    $i++;
                    }
                }
            }
        closedir($handle);
        return $result; 
        }
    else
        {
        return false;
        }   
    }

Der Kunde ist damit erstmal zufrieden, bedauert aber, das das Suchwort nicht im Anzeigetext erscheint. Kann ich auch verstehen.
wegus schrieb:
Was die Geschichte mit booleschen Ergebnissen angeht, das ist in PHP nach wie vor kritisch. Gaaanz früher gab es kein true und false. Da war 0==false und 1==true. Das wurde später geändert und zieht in einigen Dingen bis heute Fäden. Ich schaue daher immer zuerst nach solchen Fehlerquellen. Aus den gleichen Gründen benutze ich auch kein is_integer
oder ähnliches. Die haben früher schlicht nicht zuverlässig gearbeitet und ich habe mir mit der Zeit eine eigene Bibliothek (ähnlich pear nur viel spezieller und nat. kleiner) an Funktionen und Classes erzeugt. Generell gilt, trau keiner PHP Fehlermeldung und im Notfall alles per print/print_r kontrollieren...

Ich hoffe das reicht um Deinen Indexübersicht zu erstellen

Im Prinzip bin ich ja schon fast am Ziel nun. Es wird ein String mit definierte Länge ausgeben und ich weiss auch theoretisch, wie ich einen sauberen Offset hinbekomme. Ich versuche nun, das ganze noch dahingehend zu ändern, das der Offset bzw. das Limit soweit innerhalb einer Toleranz verschoben wird, das keine Wörter mehr abgeschnitte werden.

Vielen Dank!

Yves
 
Was mich nicht wundert, war es doch beim 2ten Aufruf ein strrpos mit zwei r für reverse. Dann sollte es funktionieren!

Dein Vertrauen ins Bound-Checking in allen Ehren, ich bin vermutlich von alten PHP-Versionen verdorben und da chronisch kritisch. Auch bin ich so was von C gewohnt. Da gilt auch "besser iss das".
 
Hi,

den reverse kannte ich nicht… hätte ich mal genauer hinsehen sollen :) Vielen Dank. So klappt es. Ich poste mal im Laufe des Tages oder morgen dann mein Ergebnis.
Liebe Grüße

Yves
 
Zurück
Oben Unten