PHP Mit PHP Wörter wie "meeeeein" finden

Caliban86

Lieutenant
Registriert
Juli 2007
Beiträge
608
Hi Leute,

Ich programmiere gerade ein kleines Script, wo ich eine Textbox aus einem Formular auswerte. Das ganze ist ein Script für eine Community, wo ich mir automatisierst bestimmte Wörter im Text durch einen BBCode ersetzen lasse.

Dabei suche ich alle Wörter die ich gerne fabrlich markieren möchte wie z.B. "Ich", "Mein", "Meins", "Deins" uuund so weiter...

das klappt mit str_replace alles schon wunderbar, nur wie sieht es jetzt aus wenn jemand das Wort "meins!" z.B. "meeeeeeeeinsss!" geschrieben hat? Wie kann ich das Wort so finden und mit einem BBCode umschließen?

Also wichtiger ist jetzt hier eig nur wie ich das Wort finden kann. Hab mich so nahe damit noch nicht befasst aber gibt es vielleicht eine Art Suchmuster wie

"finde alles was wie "mein" klingt"?

Ich denke ihr wisst was ich meine... Ich will alle Wörter finden die absichtlich mit mehreren Buchstaben geschrieben wurden, wie halt "meeeein", "mmmeinnns" uuusw.

hoffe ihr wisst was ich meine und könnt mir da eventuell helfen! :)


vielen Dank schonmal im vorraus! :)


Gruß Crestfallen
 
ich bin in sachen programmieren eher ein amateur, aber ich würde eine funktion schreiben, mit welcher jedes wort aus deiner textbox einzeln überprüft wird. diese funktion überprüft dann jeden einzelnen buchstaben des wortes und vergleicht den ersten buchstaben mit dem danach folgenden. sind buchstabe und nachfolgender buchstabe gleich, so wird der nachfolgende buchstabe entfernt und die prozedur wiederholt. sind buchstabe und nachfolgender buchstabe verschieden, so springt die überprüfung um einen buchstaben nach vorne, bis eben das wort zuende ist.
so werden dann also alle mehrfach hintereinander folgende buchstaben auf einen beschränkt und es kann überprüft werden ob das wort zu denen gehört, welche du einfärben willst. (meeeeeeeeiiiins -> meins).
dann hast du jedoch ein problem mit wörtern welche von natur aus doppelte buchstaben haben, denn "immer" -> "imer". willst du also immer das wort "immer" einfärben, so musst du das wort "imer" auf deine liste der einzufärbenden wörter setzen.

hoffe du verstehst wie ich das gemeint habe, wie gesagt: bin amateur ^^
 
Du könntest dich an regulären Ausdrücken versuchen und für jedes Wort definieren das es zwar aus der Abfolge der Buchstaben bestehen soll, diese aber jeweils beliebig oft vorkommen können. Das heisst du würdest mit einem Ausdruck "meins" finden also auch "meinnnns, meeeeiiiinnnnsssss, mmeins" usw...
 

Vielen Dank für eure Antworten aber ich glaube die Funktion von scor ist genau das was ich gesucht habe und funktionierte auf anhieb! :) Vielen Dank
Ergänzung ()

Ich glaube so ganz ist das Problem doch noch nicht gelöst, zwar funktioniert es, dass ich die Wörter mit dieser Funktion anhand von vorgegeben wörtern exakt finde, jedoch macht er das mit jedem anderen wort, welches den vorgaben nicht ähnelt genau so...

Beispielsatz:

"Ich liebe dich meeein Schatz"


Was ich nun mache ist erstmal diesen Satz mit explode in einzelne Wörter zu teilen und in ein array zu packen. Dann erstelle ich das array mit den vergleichswörtertnm sprich hier nur als beispiel "mein".

wenn ich nun die levenshtein funktion mit diesem satz als foreach schleife für jedes einzelne wort durchlaufen lasse, dann spuckt er mir jedoch bei jedem wort ein ergebniss aus.

sprich nach der funktion nach ist "Ich" ähnlich wie "mein" aus dem Vergleichswort Array. Ich habe auf der Seite auch ein Beispiel gefunden, welches einen Prozentsatz der Ähnlichkeit ausgibt. Aber auch hier komme ich zu einem komischen Ergebiss. Demnach ist das Wort "und" zu 20% gleich wie "deins". Wäre da das Ergebniss 0% könnte man das ja ganz einfach aussortieren, aber wie kommt er hier auf 20%?

Jemand eine Idee das wirklich nur die Wörter mit dieser Funktion ausgegeben werden die sich auch wirklich denen im Vergleichsarray ähneln??

Gruß Crestfallen
 
Also ich würd auch sagen, dass die einzig sinnvolle Möglichkeit die von Fynnjard ist!

Um das angegebene Problem zu umgehen könntest du bei dem wort des hervorgehoben werden soll, auch einfach die doppelten buchstaben entfernen und dann vergleichen:
siehe dieses beispiel:

im Text steht: Hallo ich bin immerwieder gerne auf dieser Internetseite
Folgende wörter sollen hervorgehoben/ersetzt(oda was auch immer) werden: Hallo, gerne
Somit macht es überall die doppelten buchstaben weg:

im test steht: Halo ich bin imerwieder gerne auf dieser Internetseite
deine wörter die ersetzt werden: Halo, gerne

somit kannst du auch in deine liste wörter mit doppelten buchstaben reinhauen.

Nur wieder ne besonderheit tritt auf wenn du zusammengesetzte wörter hast, wie zB immerwieder! wenn in deiner liste "immer" steht, soll dann "immer" ersetzt werden oder nicht? (hoffe du hast das nicht oben schonmal geschrieben, aber könnte leider grad net alles lesen)



edit: also hab mir jetz mal die levenshtein-funktion angeguckt!
kannste da nicht einfach cost_ins und cost_rep ziemlich hoch machen und cost_del einfach auf null oder 1 machen?? dann müsste es doch eigentlich hauptsächlich nur löschen oder??
 
Zuletzt bearbeitet:
Also bisher bin ich glaub ich doch mit den Regulären Ausdrücken am weitesten gekommen. Nur da hänge ich auch ein wenig fest. Bisher habe ich folgende Test Code:

$textfeld = "meeeins";

ereg_replace('^m?e+i+n+s*$', '???', $textfeld);


So, normalerweise müsste es doch gehen, dass er mit diesem Regulären Ausdruck das "meeeins" in der $textfeld Variable finden kann oder? Nur wie mache ich es dann das der gefundene Ausdruck auch wieder verwendet werden kann? Sprich da wo die "???" stehen müsste dann doch später z.B. stehen "[farbe=rot].GEFUNDENER AUSDRUCK.[/farbe]" oder sowas in der Art? Nur wie gebe ich den Ausdruck an? Es soll ja das Wort bleiben, welches er auch findet.

Nochmal wichtig zu erwähnen, weil ich denke das hat der Herr vor mir auch etwas missverstanden:

Die Wörter die wie "meeeeein" oder "deeeinnnns" geschrieben sind sollen NICHT in "mein" geändert werden, sondern es soll lediglich der BBCode um diese Wörter gelegt werden. Also soll das Wort selbst NICHT geändert werden und so bleiben.

Mit der Funktion ereg ging es allerdings mit dem Ausdruck wie oben. Dort hat er dann immer eine 1 zurückgegeben wenn der Ausdruck gefunden wurde. Wieso geht das mit ereg_replace hier nicht?
 
deine wörter müssen doch nicht unbedingt dadurch verändert werden!

du hämerst zB alle wörter in ein array, verkürzt diese, lässt überprüfen wo im array jetz ein code eingefügt wurde(bzw lässt halt auch immer bei einem fund einfach in ein anderes array schreiben das wievielte wort es war) und dann ist deine kreativität gefragt die dinger wieder zusammenzubasteln, dass es für deinen zweck passt!

musst halt nur schauen dass halt ein deinem ursprungarray nichts überschrieben/gelöscht wird, sondern vllt einfach wenn jetzt zB das 10te wort gefunden wurde, einfach im array mit dem index 10 einfach was vorne oder hinten (bzw vorne und hinten) hingehängt wird (eben zB BBCode)
 
Ich denke das Problem ist jetzt gelöst... Bin nun bisher wirklich mit den Regulären Ausdrücken am sinnvollsten weiter gekommen:

$textfeld = "meeeeeins und meeeiiiinnnnnssss";
$textfeld = ereg_replace('m?e+i+n+s*', '^4\\0^f', $textfeld);


Das Ergebniss ist nun anschließend: ^4meeeeeins^f und ^4meeeiiiinnnnnssss^f


Genau so soll es am Ende aussehen :)


vielen Dank noch mal für eure Hilfe!
 
Alternativ zum Levenshtein Algorithmus wären folgende Funktionen vielleicht noch passend (müssteste einfach mal mit deinen Beispielwörtern durchspielen)

http://www.php.net/manual/de/function.similar-text.php
http://www.php.net/manual/de/function.soundex.php

Regexp ist mmn. übrigens nicht die Paradelösung, da es ziehmlich böse auf die Performance geht

// edit
Levenshtein gibt dir übrigens immer ein Ergebnis zurück, da der Sinn darin besteht das passenste Wort zu finden! Guck dir die Kommentare unter der Funktionsbeschreibung mal an, da sind einige sehr gute Ansätze bei!

// edit #2
siehe http://wg-morpork.de/test.php so in der Richtung stellst du dir das doch vor, oder?
 
Zuletzt bearbeitet:
Zurück
Oben