Nach Schlagwörtern suchen

Hallo liebe Community,

eine Suchmaske ist gegeben in die man einen Text eingibt. Dieser Text wird abgeschickt und in eine Variable gepackt, so weit auch alles kein Problem. Aber wie stelle ich es an dass in PHP dann der Inhalt der Variable nur nach bestimmten Wörtern durchsucht wird und dann ein für das Schlagwort vordefinierter Ausgabetext angezeigt wird?

Konnte dazu keine Funktion finden.

Hoffe ihr könnt mir helfen.

Mit freundlichen Grüßen

MaxT :wink:

Wenn das nur einfacher Text ist, kannst du doch die Stichwörter
in ein array packen und auf den Text dann nacheinander für
jedes Stichwort eine Suchfunktion von PHP anwenden lassen -
welche da am besten ist, hängt davon ab, was man genau
wissen will - wo der Suchbegriff steht oder wie oft er vorkommt
etc…

Danke für deine schnelle Antwort aber ich kann mir nicht ganz vorstellen wie das funktionieren soll ich will ja nicht die Schlagworte per Zufall ausgeben oder so etwas in der Art.

Man gibt einen Satz ein, der wird durchsucht nach bestimmten Wörtern, kommt ein Kombination gespeicherter Schlagwörter vor wird zugehörige Antwort gegeben.

Also wenn ich mal wieder zu schlecht erklärt habe dann tut es mir leid andern Falls wäre ich dir überaus dankbar wenn du mir kurz einen Beispiel-Code geben könntest. :slight_smile:

Liebe Grüße

MaxT :wink:

Kommt es auf die Reihenfolge an, in der die Schlagwörter
gefunden werden?

Wenn nicht, ist das recht übersichtlich.
Man kann dann zwei arrays definieren, eines mit dem
Schlagwörtern, eines mit der Anzahl:

# Schlagwörter und Anzahl
$schlag[0]='ich';
$anzahl[0]=0;
$schlag[1]='du';
$anzahl[1]=0;
$schlag[2]='er';
$anzahl[2]=0;
$schlag[3]='sie';
$anzahl[3]=0;
$schlag[4]='es';
$anzahl[4]=0;

# zu analysierender Text:
$text='du und ich gehn essen.'

# Schleife zur Analyse:
for ($i = 0; $i <= 4; $i++) {
  $anzahl[$i]=substr_count($text, $schlag[$i]);
}

# Auswerten z.B. so:
if (($anzahl[4]>0) AND ($anzahl[0]>0) ) {
  echo "ich und es kommen vor";
}

Man beachte, daß substr_count zwischen Groß- und
Kleinschreibung unterscheidet, will man das nicht, kann man
$text zunächst in Kleinbuchstaben konvertieren:
$klein = strtolower($text);
Und dann $klein statt $text analysieren.

Alternativ kann man auch stripos() statt substr_count()
verwenden, wenn man die Anzahl gar nicht genau wissen will.
Oder eben strpos. Da ist die Auswertung dann etwas anders,
da fragt man dann nur ab, ob das Ergebnis nicht der Boolsche
Wert ‘false’ ist.

Da gibt es zahlreiche Varianten, mehr oder weniger elegant oder
schwierig oder verständlich, je nachdem, was man gern hätte.

php.net/manual/de/function.stripos.php

Vielen lieben Dank,

allerdings wird mir bei dem obigen Script syntax error, unexpected T_FOR in Zeile 18 angezeigt.
Zeile 18 wäre in dem Fall die Zeile unter “# Schleife zur Analyse:” angezeigt.

Habe schon die beiden “++” entfernt und die geschweifte Klammer in die nächste Zeile gesetzt, hat nichts gebracht.

Liebe Grüße

MaxT :wink:

Bei unexpected Fehlern liegt der eigentliche Fehler oft darüber
Hier

fehlt ein ;

Also nur ein kleiner Tippfehler :wink:

Ich danke euch, alles funktioniert reibungslos und lies sich wunderbar implementieren! :slight_smile:

Mein code sieht nun wie folgt aus:

[code]<?php

Schlagwörter und Anzahl

$schlag[0]=‘wetter’;
$anzahl[0]=0;
$schlag[1]=‘sommer’;
$anzahl[1]=0;
$schlag[2]=‘1910’;
$anzahl[2]=0;

zu analysierender Text:

$text = $_POST[‘textarea’];
$klein = strtolower($text);

Schleife zur Analyse:

for ($i = 0; $i <= 2; $i++) {
$anzahl[$i]=substr_count($klein, $schlag[$i]);
}

Auswerten z.B. so:

if (($anzahl[0]>0) AND ($anzahl[1]>0) ) {
echo “warm”;
}

Auswerten z.B. so:

if (($anzahl[0]>0) AND ($anzahl[1]>0) AND ($anzahl[2]>0) ) {
echo “22°C”;
}
?>[/code]

Dies ist nun ein kleiner Ausschnitt für einen leichten Überblick. Allerdings bin ich schnell auf ein Problem gestoßen.

Gibt man bei obigem Script nun in das Textfeld “Wie war das Wetter im Sommer?” ein so erscheint als Antwort “warm”. Dies ist so weit auch korrekt. Allerdings wenn nun die Eingabe erweiterte wird auf: “Wie warm war das Wetter im Sommer 1910?” so scheint als Antwort “warm22°C” da beide Abfragen zutreffen.

Gibt es irgendeine Möglichkeit dies zu beheben? Man könnte mehre Abfragen verschachteln und genauer Abfragen allerdings bei mehreren zusätzen ergäbe dies unendlich viele Kombinationen weshalb ich diese Lösung nicht begrüße.

Natürlich könnte man festlegen sobald weitere Schlagwörter außer “wetter” und “sommer” gefunden werden die erste Abfrage nicht mehr zutrifft, also das die Abfragen nur zutreffen wenn wirklich nur diese Schlagwörter enthalten wären und keine weiteren. Jedoch mit steigender Anzahl an eingetragenen Schlagwörtern wäre es dann fast unmöglich noch Antworten zu geben da sicherlich in der Frage des Nutzers ein weiteres Schlagwort noch vorkommt.

Hoffe ich konnte das Problem gut beschreiben. Mir fällt einfach kein sauberer Lösungsweg ein der auch mit vielen Schlagwörtern gut funktioniert. :neutral_face:

Also eine Art “Nur-Befehl” würde schon helfen, dass eben die Antwort der ersten Abfrage nur dann erscheint wenn nur exakt die beiden Schlüsselwörter Wetter und Sommer vorkommen, kommen weitere Schlüsselwörter vor greift eine andere Abfrage, dies gäbe zwar einige Möglichkeiten wäre aber eine denkbare Lösung. Allerdings ist mir kein PHP-Element bekannt welches dies ermöglicht dass eben exakt diese Schlüsselwörter vorhanden sein müssen und eben nicht nur “unter anderem diese Schlüselwörter vorhanden sein müssen”.

Liebe Grüße

MaxT :wink:

Bei dem einfachen Beispiel kannst du natürlich einfach die
speziellere Bedingung nach vorne setzen und die allgemeinere
nach hinten und dann beides mit ‘else if’ verbinden.

Willst du hingegen nur Fragen zum Wetter an einem bestimmten
Datum beantworten, so bietet es sich an, die Eingabe zu
formalisieren, also Eingabe des Datums im internationalen
Datumsformat - wenn du die Daten entsprechend abgelegt
hast, brauchst du nichtmal eine Datenbank oder eine Suche,
um die Antwort rauszurücken.

Sobald es allerdings unüberschaubar wird, wonach gesucht
werden wird, empfiehlt es sich, die Antworten in einer Datenbank
abzulegen und dann dort mit den Schlüsselwörtern zu
korrelieren.

Damit ein Programm allerdings wirklich ‘versteht’, was gefragt
wurde, müßte das Teil ja den Satzbau analysieren, Fehler
tolerieren, kurzum, du müßtest ein Programm zur artifiziellen
Intelligenz schreiben, was nicht trivial ist und für einige Leute
aktuelles Forschungsgebiet.
Wie man beim Google sieht und auch bei anderen Diensten, wo
man wirklich Fragen eingeben kann, sind die Antworten oft
unbefriedigend, weil die Frage nicht verstanden wurde, sondern
’nur’ Korrelationen zu Stichwörtern geliefert werden. Am Beispiel
der Suchmaschinen sieht man sehr deutlich, daß es für ein
Programm nicht einfach ist, eine frei formulierte Frage sinnvoll
zu bearbeiten.

Vielen lieben Dank nochmal, funktioniert alles und lies sich wunderbar implementieren. Danke. :slight_smile:

Sicherlich, die Grenze ist fast schon erreicht, allerdings benötige ich ja nur etwas simples und nicht etwas bei dem die Grenze zu KI schon verschwimmt. :smiley:

Das Thema Rechtschreibfehler konnte ich nun schon beseitigen mit folgender Lösung:

# Auswerten z.B. so: if (($anzahl[4]>0) AND (($anzahl[0]>0) OR ($anzahl[2]>0))) { echo "Test"; }

0 ist z.B. das richtige Wort, und 2 das selbe mit einem kleinen Rechtschreibfehler.

Das Thema Wetter war nur ein Beispiel, tut mir leid.

Zur Zeit arbeite ich mit mehreren Wörtern als Satzteile, damit lässt sich das ganze schon ein gutes Stück erleichtern.

Nun würde mir nur noch eine Art “ONLY-Befehl” fehlen mit dem ich eben wie oben schon beschrieben festlegen kann dass die Antwort der Abfrage nur erscheint wenn wirklich NUR die in der Abfrage vorhanden Schlüsselwörter im eingegebenen Text erscheinen und keine weiteren. Für jede Schlüsselwort-Kombination liese sich dann eine extra Abfrage anfertigen.

Gibt es solch einen Befehl oder ein Element?

Liebe Grüße

MaxT :wink:

‘only’ kannst du durch geringfügiges Nachdenken selbst erreichen.
Einfach die Summe der Anzahl der unerwünschten Schlagwörter
bilden und testen, daß diese 0 ist.

Wenn du wirklich testen willst, ob in der Zeichenkette auch
Wörter vorkommen, die nicht als Schlagwörter vorliegen,
müßtest du etwas anders vorgehen, am besten erstmal die
üblichen Satzzeichen aus der Zeichenkette entfernen,
Zeilenumbrüche durch Leerzeichen ersetzen, mehrfache
Leerzeichen durch ein Leerzeichen ersetzen, anhand der
Leerzeichen ein array erzeugen lassen (Funktion explode)
und dann gucken, ob oder welche Elemente von dem neuen
array im alten vorkommen und welche nicht.

Tut mir leid, ich stehe gerade etwas auf dem Schlauch.

[ul]Einfach die Summe der Anzahl der unerwünschten Schlagwörter
bilden und testen, daß diese 0 ist.[/ul]

Würde es sehr gerne verstehen, wäre dir sehr dankbar für ein kleines Beispiel. :slight_smile:

Mit freundlichen Grüßen

MaxT :wink:

Daß das funktioniert, liegt daran, daß die Anzahl immer eine
nicht negative Zahl ist.

Sind etwa die Schlagwörter 1, 5, 7 und 9 unerwünscht, so kann
man schreiben:

$summe=$anzahl[1]+$anzahl[5]+$anzahl[7]+$anzahl[9];

if (($anzahl[4]>0) AND ($summe==0) ) {
  echo "Schlagwort 4 kommt vor, 1, 5, 7 und 9 aber nicht";
}

Sind alle bis auf ein Schlagwort unerwünscht, kann man auch
mit einer for-Schleife über alle summieren und anschließend
die $anzahl vom erwünschten wieder abziehen - oder man
fragt in der zweiten Bedingung einfach, ob die Summe gleich
$anzahl des gewünschten Schlagwortes ist - etc, eben elemenare
Rechnerei, wie man sie auf der Grundschule lernt (-e, zumindest
zu meiner Zeit ;o)

Vielen Dank!

Durch das Beispiel ist mir ein weiterer lösungsweg eingefallen. Man könnte jeder einzelnen Variablen(Schlagwort) verschiedene Zahlenwerte zuweisen (völlig krumme und große, z.B. 7812036984).

Dann zu jedem Schlagwort eine Abfrage "Wenn Schlagwort vorhanden dann $summe+7812036984.

Sind dann zwei Schlagwörter enthalten ist $summe = Wert von beiden Schlagwörtern. Durch die großen Zahlen ist es auch realtiv unwahrscheinlich dass andere Kombinationen das Selbe ergeben.

Und Am Ende eben bei einer Abfrage “wenn $summe = 54684616875346 dann AntwortNr.XY ausgeben”.

Vielen Dank,

werde mich melden wenn alles fertig ist. :wink:

Für den Ansatz verwendest du besser eine binäre Darstellung,
für jedes Schlagwort ein Bit, dann ist das Ergebnis eindeutig.
Kommt das Schlagwort mindestens einmal vor, so setzt man
das jeweilige Bit auf 1, sonst nicht. Kann man als binäre Zahl
aufschreiben, aber auch als Zeichenkette.

Mit der Zahl lassen sich dann bei Bedarf mit PHP auch binäre
Operationen ausführen, um kompliziertere logische
Zusammenhänge effektiv zu formulieren.

Eine Zahl wie 100110 bedeutet dann eben, Schlagwort 0, 3 und
4 kommen nicht vor, 1, 2 und 5 kommen vor.

Ich melde mich leider jetzt bereits wieder. :smiley:

Ich habe das Ganze ersteinmal umgeworfen. Als Schlagworte definiere ich ganze Fragen bzw. einzelne Bausteine von Fragen da es im Grunde nur etwa 40 Fragen gibt. Erst wenn es mehr werden benötige ich eigentlich das Ganze (dieser Fall wird sicherlich eintreten. g).

Allerdings bin ich auf ein weiteres kleines Problem gestoßen.

$schlag[15]='weshalb ist der himmel blau'; $anzahl[15]=0; $schlag[16]='warum ist der himmel blau'; $anzahl[16]=0; $schlag[17]='wieso ist der himmel blau'; $anzahl[17]=0;

Natürlich haben wieso, weshalb und warum unterschiedliche Bedueutungen bzw. erwarten andere Antworten aber diese drei Worte dienen hier mal nur als Beispiele schließlich könnte man als ausßreichendes Schlagwort in dem beispiel auch nur “ist der himmel blau” verwenden da dies sicherlich in kaum einer anderen Frage vorkommen würde.

Nun wäre es spitze wenn man nicht alles 3x schreiben müsste (bei mehreren austauschbaren Wörtern würde dies auch noch exponentiell steigen…). Zuerst kam mir folgende Idee:

$schlag[15]='$w ist der himmel blau'; $anzahl[15]=0;

Allerdings ist mit recht schnell eingefallen dass man einer Variablen nicht mehrere Werte auf einmal zuweisen kann. Ein “OR”-Befehl lässt sich natürlich auch nicht in das Schlagwort reinpressen.

Gibt es überhaupt eine einfache Lösung Platzhalter auf diese Art einzusetzen?

Liebe Grüße

MaxT :wink:

Da wirst du wohl früher oder später einen genaueren Blick auf
reguläre Ausdrücke werfen müssen und wie man die in PHP
verwendet. Damit kann man letztlich recht effizient eine Eingabe
in etwas konvertieren, was die weiteren Möglichkeiten der
Verarbeitung reduziert.

Die einfachen PHP-Funktionen zum Zählen oder Finden von
Zeichenketten sind sehr schön, um schnell ein einfaches Problem
zu lösen - je umfangreicher die Anforderungen werden, desto
abstrakter und mächtiger wird das benötigte Werkzeug - und das
sind dann wohl letztlich die regulären Ausdrücke.

Allerdings, wenn sowieso nur eine endliche Anzahl von Fragen
beantwortet werden kann, kann man die ja auch gleich direkt mit
einer Auswahlliste ohne Ähnlichem ins Eingabeformular schreiben
und erspart sich damit gleich eine Menge Arbeit, weil dann der
Nutzer gar nicht erst eingeben kann, womit man sowieso nichts
anfangen kann ;o)

Textverwurstung in PHP:
php.net/manual/de/refs.basic.text.php