Helpdesk
Menschen Wissenschaft Politik Mystery Kriminalfälle Spiritualität Verschwörungen Technologie Ufologie Natur Umfragen Unterhaltung
weitere Rubriken
PhilosophieTräumeOrteEsoterikLiteraturAstronomieHelpdeskGruppenGamingFilmeMusikClashVerbesserungenAllmysteryEnglish
Diskussions-Übersichten
BesuchtTeilgenommenAlleNeueGeschlossenLesenswertSchlüsselwörter
Schiebe oft benutzte Tabs in die Navigationsleiste (zurücksetzen).

PHP custom site search programmieren

65 Beiträge ▪ Schlüsselwörter: PHP, Preg_replace, Search ▪ Abonnieren: Feed E-Mail
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

02.08.2012 um 22:01
Hi,

ich mache einen Site-Search auf meine Website und bin auch schon recht weit gekommen. In diesem Thread werde ich Fragen stellen, welche sich mir auf dem Weg dorthin stellen.

Angefangen mit dem Problem hier:

Diese Funktion soll eine Zeichenkette caseunsensitiv in einem String mit HTML Tags umschließen. Es funktioniert fast, nur die Zeichenkette wird immer bis zum Ende des Wortes umfasst. Was ich brauchen würde, wäre es, dass das schließende Tag auch mitten im Wort gesetzt wird, wenn die gesuchte Zeichenkette da schon zu Ende ist.

Dabei enthält $array die gesuchten Zeichenketten.

function hilite($string, $array){ return preg_replace('~('.implode('|', $array).'[a-zA-Z] {0,45})(?![^<]*[>])~is','$0', $string ); }


melden

PHP custom site search programmieren

02.08.2012 um 22:33
@AnGSt Nicht so kompliziert ;) <?php // charset=utf-8 header('Content-Type: text/html; charset=utf-8'); $string = "text suche 1 text Suche 2 text sUcHe 3 text"; echo "Input: ".$string." "; $array = array(); $array[0] = "suche 1"; $array[1] = "suche 2"; $array[2] = "suche 3"; $output = ""; $output = replace($string, $array); unset($string, $array); // speicherfreundlich arbeiten ;) echo "Output: ".$output." "; function replace ($string, $array) { $func_count = count($array); for ($i=0; $i < $func_count; $i++) { $string = preg_replace('#('.$array[$i].')#i', '[b]$0[b]', $string); } return $string; } ?>


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

02.08.2012 um 22:40
Danke Dir aber warum machst Du es nicht dann auch so:

function hilite($string, $array) { foreach ($array as $key) { $string = preg_replace('#('.$key.')#i', '$0', $string); } return $string; }

@acc


melden

PHP custom site search programmieren

02.08.2012 um 22:48
@AnGSt Ist Jacke wie Hose, bleibt die selbe Funktion :D


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

02.08.2012 um 23:11
@acc

Kann ich irgendwie ermitteln wie oft etwas ersetzt wurde? brauche ich dazu callback?

Ich denke der Paramter 'anzahl' in preg_replace bekommt die Zahl der Treffer gutgeschrieben. :)


melden

PHP custom site search programmieren

02.08.2012 um 23:31
@AnGSt <?php // charset=utf-8 header('Content-Type: text/html; charset=utf-8'); $string = "text suche 1 text Suche 2 text sUcHe 3 text suche 2 text"; echo "Input: ".$string." "; $array = array(); $array[0] = "suche 1"; $array[1] = "suche 2"; $array[2] = "suche 3"; $output = array(); $output = replace($string, $array); unset($string, $array); // speicherfreundlich arbeiten ;) echo $output['count']." Treffer: ".$output['string']." "; function replace ($string, $array) { $count = 0; foreach ($array as $key) { $string = preg_replace('#('.$key.')#i', '[b]$0[/b]', $string, -1, $func_count); $count = $count + $func_count; } $func_out = array('string' => $string, 'count' => $count); return $func_out; } ?>


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

02.08.2012 um 23:35
@acc

Musst Du nicht $func_count erst definieren bevor Du es an preg_replace übergeben darfst?


melden

PHP custom site search programmieren

02.08.2012 um 23:38
@AnGSt

Führt zwar nicht zwingend zu einem Fehler, sollte man der Ordnung halber aber machen, ja ;)


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

02.08.2012 um 23:45
Überlegungen haben ergeben, dass eine Linkreferenz an den nächstgelegenen Sprung-Anker vor dem gefundenen Keyword nicht möglich ist, sofern man für den Anker nicht das name attribut vom a tag verwendet sondern das id attribut von zB der Unterüberschift an die man springen könnte. Stimmt das? Oder gibts noch eine andere Lösung?


melden

PHP custom site search programmieren

02.08.2012 um 23:47
Kommt drauf an wie du dir die Umsetzung genau vorstellst. Willst du per Button die Treffer durchspringen?


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

02.08.2012 um 23:51
@acc

Ich will eine .php Webseite machen, an die der Suchbegriff / die Suchbegriffe per POST übergeben werden und welche dann vor der Ausgabe der Ergebnisse diese in den intern angegebenen anderen .php Seiten sucht. pro Seite kann ich mehrere Snippets ausgeben und die Seite steigt im Ranking je mehr Worte in allen ihren Snippets gefunden worden sind. Beantwortet das Deine Frage?


melden

PHP custom site search programmieren

02.08.2012 um 23:54
@AnGSt Ich meinte eher wie du dir die Funktionalität vorstellst, im Bezug auf das per Anker "hin springen". Willst du damit von einem Suchergebnis zum anderen springen oder wozu solls genau dienen?


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

02.08.2012 um 23:56
@acc

In der Liste der Ergebnisse sind links. Normalerweise gehen die direkt auf die gefundene Seite. Aber was mich interessieren würde, ob man auf der Zielseite auch direkt in die Nähe des gefundenen Begriffs springen kann oder so. Also vom Link aus gehend, oder anders?


melden

PHP custom site search programmieren

03.08.2012 um 00:06
@AnGSt

Ja, aber das ist etwas tricky. Weil du dazu ja den Content der Seiten manipulieren mußt, aber eben nur für den derzeitigen Aufruf. Es soll ja nicht der nächste Seitenbesucher den manipulierten Content bekommen. Der soll ja nur für den Aufrufer der Suchfunktion temporär manipuliert und ausgegeben werden. Manipuliert = den Content den Keys entsprechend mit Anker versehen.

Also ich persönlich finde den Aufwand nicht gerechtfertigt, da jeder gute Browser über eine Suchfunktion verfügt, die farblich hervorhebt und mit der man von Treffer zu Treffer springen kann auf der Seite.


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

03.08.2012 um 00:07
@acc

ok, hast mich überzeugt. :)


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

03.08.2012 um 11:11
Jetzt kommt die Monster-Match-Routine. Folgender Code extrahiert mir einen Bereich um ein Schlüsselwort herum aus einem Text. $haystack ist der text und $needle ist das Schlüsselwort.

function summarize($haystack,$needle,$wordLimit = 20) { $preg_safe = str_replace(" ", "\s", preg_quote($needle)); $pattern = "/(\w*\S\s+){0,$wordLimit}\S *($preg_safe)\S*(\s\S+){0,$wordLimit}/ix"; if (preg_match_all($pattern, $haystack, $matches)) { $summary = $matches[0][0]; } else { $summary = false; } return $summary; }

Die Funktion hat aber Probleme mit unicode-chars wenn sie links vor dem Schlüsselwort stehen (Zeichen wird verhunzt und der Ergebnisstring endet dort) und sie bricht in beide Richtungen bei "-" Zeichen ab. Beides sollte nicht sein.

Außerdem möchte ich auch die Position im Text ab der gesucht werden soll als Parameter übergeben und auch die Position nach dem gefundenen Textauszug zurück erhalten oder so. Wenn ich das nächste Vorkommen des selben Schlüsselwortes untersuche, soll ja nicht wieder am Anfang angefangen werden.

Und wenn nach mehreren Keywords gesucht wird und von diesen mehrere innerhalb des Textauszuges sind, dann sollte erstens nicht für jedes Schlüsselwort ein eigener Auszug generiert werden und zweitens sollte der Auszug dann erst um $wordLimit Worte nach dem _letzten_ im Auszug vorkommenden Schlüsselwort enden.

Vielleicht kann man diese Anforderungen in einer Funktion vereinen?


melden

PHP custom site search programmieren

03.08.2012 um 13:42
oh man, du machst ja sachen ;)
wäre es nicht einfacher gewesen von vorn herein ein fertiges cms zu verwenden? ;)
ich wünsch dir dennoch viel spass bei der sache. würde dir gern bei dem problem helfen, hab aber eine entzündung in der schulter, sodass ich das ipad nicht allzu lange halten kann. have fun


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

03.08.2012 um 18:35
Danke ich werde es genießen. :) Aber vielleicht kann @acc noch etwas dazu sagen? Ich denke gerade über eine Lösung nach, in der ich das Ganze in einzelne Worte zerlege und einfach mit zähle ab der Position wo ich fündig wurde. Ist dort danach in der Nähe noch ein weiteres passendes Wort, wird der 20-Worte Zähler zurückgesetzt. Für den Match langt es dann wenn ich schaue ob denn der Schlüsselbegriff überhaupt im Wort vor kommt. Nachteil dieser Methode: es können keine Phrasen gesucht werden, ich meine Schlüsselbegriffe mit Space darin. Es gibt sicher noch eine Menge Techniken für solche Fragen.


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

03.08.2012 um 22:11
Ich habs jetzt so gemacht mit dem nach Worten aufteilen und durchgehen. Wird nach einer Phrase gesucht, wird diese auch gefunden, weil die einzelnen Worte der Phrase als einzelne Suchbegriffe genommen werden.


melden
AnGSt Diskussionsleiter
ehemaliges Mitglied

Link kopieren
Lesezeichen setzen

PHP custom site search programmieren

03.08.2012 um 23:16
Das ist jetzt meine Suchfunktion:

function getsnippets ($text,$keywords,$limit = 6,&$counter = 0) { // Returns array of snippets with macthing keywords from a text or false! // Gets $keywords array and opt. a pointer to a counter variable where to // put the number of matched words. // $limit can be the number of words to extract before or after a matching // keyword. If there are up to $limit words between two matches, the are // taken together into one snippet. $words = explode(" ",$text); unset($text); $num_words = count($words); for ($pos=0; $pos < $num_words; $pos++) { foreach ($keywords as $keyword) { if ($words[$pos] && stripos($words[$pos], $keyword) !== false) { $counter += 1; $left = ($pos-$limit >= 0) ? $pos-$limit : 0; // step forward up to $limit words as $right, reset step if another keyword found $right = $pos; while ($right + 1 < $num_words && $right - $pos < $limit ) { $right += 1; foreach ($keywords as $keyword) { if (stripos($words[$right], $keyword) !== false) { $counter += 1; $pos = $right; } } } $pos = $right; // snippet left and right found $part = array_slice($words,$left,$right-$left+1); $snippets[] = implode(" ",$part); } } } if (isset($snippets)) return $snippets; else return false; }


melden