Wörtchen wechsel dich
AllesMeins
- php
0 ChrisB0 ChrisB
0 Tom0 Cheatah0 dedlfix0 dedlfix
0 Texter mit x0 Danke!
AllesMeins0 Tom
Hi,
ich bräuchte mal etwas Inspiration wie ich ein Problem auf möglichst elegante Weise lösen kann. Ich stehe hier gerade echt auf dem Schlauch, wie ich das effektiv angehen kann. Also folgendes:
Ich habe eine Liste mit Wortpaaren (so in der Größenordnung 100 Einträge, also nichts unhandhabbares). Ich möchte nun einen Eingabe-String bearbeiten indem ich ein Wort jeweils durch seinen Partner ersetze. Und das in beide Richtungen. Also wenn in der Liste das Wort-Paar: Hund - Katze steht, so soll jedes Vorkommen von Hund durch "Katze" ersetzt werden, aber auch jede "Katze" durch "Hund".
Und das für alle Wörter der Liste.
Mein Problem ist nun dass ich irgendwie sicherstellen muss dass ein einmal ersetztes Wort nicht wieder zurück geändert wird. Also wenn ich einfach die Liste durcharbeiten würde und erst ein $string = str_replace("Katze","Hund",$string) mache und dann ein str_replace("Hund","Katze",$string) ersetze ich damit ja auch die eben erst "erzeugten" Hunde. Arbeite ich auf Kopien der Strings müsste ich sie danach wieder irgendwie clever mergen und dabei wissen was erhalten bleiben muss und was nicht. Das löst das Problem also auch nicht.
Hinzu kommt noch, dass enzelne Wörter Teilwörter von anderen sein können. Also beispielsweise könnte ein Wortpaar Tür - Türklinke sein. Dabei muss sichergestellt sein, dass aus der Eingabe "Türklinke" nicht "Türklinkeklinke" wird - die Ersetzung sollte also immer erst möglichst große Treffer finden.
Kann mir hier irgendwer auf die Sprünge helfen, wie ich das elegant und effektiv lösen kann?
Hi,
Mein Problem ist nun dass ich irgendwie sicherstellen muss dass ein einmal ersetztes Wort nicht wieder zurück geändert wird. Also wenn ich einfach die Liste durcharbeiten würde und erst ein $string = str_replace("Katze","Hund",$string) mache und dann ein str_replace("Hund","Katze",$string) ersetze ich damit ja auch die eben erst "erzeugten" Hunde.
Dann ersetze "Hund" nicht durch "Katze", sondern durch "*Katze*" (bzw. benutze ein anderes Sonderzeichen, welches im Text garantiert nicht vorkommt).
Und ersetze nur dann, wenn das Wort nicht bereits durch dieses Sonderzeichen eingeklammert ist - per regulärem Ausdruck mit lookahead/lookbehind-assertions.
Hinzu kommt noch, dass enzelne Wörter Teilwörter von anderen sein können. Also beispielsweise könnte ein Wortpaar Tür - Türklinke sein. Dabei muss sichergestellt sein, dass aus der Eingabe "Türklinke" nicht "Türklinkeklinke" wird - die Ersetzung sollte also immer erst möglichst große Treffer finden.
Dann sortiere die Suchworte der Länge nach absteigend, bevor du mit dem ganzen Zirkus beginnst.
MfG ChrisB
Hi,
Ergänzung:
Dann ersetze "Hund" nicht durch "Katze", sondern durch "*Katze*" (bzw. benutze ein anderes Sonderzeichen, welches im Text garantiert nicht vorkommt).
Und ersetze nur dann, wenn das Wort nicht bereits durch dieses Sonderzeichen eingeklammert ist
Das allein wird nicht ausreichen, wenn du "Katze" bereits durch "*Hund*" ersetzt hast, und dann auch noch das kürzere "Hun" zum Ersetzen ansteht.
Alternative wäre, "Katze" durch "*H*u*n*d*" zu ersetzen - dann findet die anschliessende Suche nach "Hund" und "Hun" das auch nicht mehr.
Wenn das Sonderzeichen im Text garantiert nicht vorkommt, dann kann man das einfach so machen, und am Ende das Sonderzeichen einfach wieder rauslöschen.
Wenn doch - dann muss man die natürlichen Vorkommen dieses Zeichens zunächst maskieren - bspw. jedes * durch ** ersetzen. Beim wieder Herauslöschen werden dann nur die * ersetzt, vor denen kein * steht (RegEx).
MfG ChrisB
Hello,
Kann mir hier irgendwer auf die Sprünge helfen, wie ich das elegant und effektiv lösen kann?
Hier mal die Lösung für singlebytecodierten Text:
Den Text an dem längeren der beiden Wörter exploden.
http://de2.php.net/manual/en/function.strlen.php
und für Allesineinezeilequetscher der ternäre Operator. Den Link dazu finde ich immer nicht.
http://de2.php.net/manual/en/function.explode.php
Dann das Array durcharbeiten und in den Elementen das kleinere Wort suchen und ersetzen lassen.
http://de2.php.net/manual/en/function.array-map.php
http://de2.php.net/manual/en/function.str-ireplace.php oder die casesensitive Funktion dazu
und dann das große Array mit dem Ersatzkitt wieder zusammenkleben.
http://de2.php.net/manual/en/function.implode.php
Ich glaube, dass diese Lösung soger eine für Allesineinezeilequetscher sein könnte.
Würde ich aber nicht machen, sondern es explizit hinschreiben :-))
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi,
Also wenn in der Liste das Wort-Paar: Hund - Katze steht, so soll jedes Vorkommen von Hund durch "Katze" ersetzt werden, aber auch jede "Katze" durch "Hund".
achte auf die Möglichkeiten des Parameters $replacement bei preg_replace.
Cheatah
Hi!
Mein Problem ist nun dass ich irgendwie sicherstellen muss dass ein einmal ersetztes Wort nicht wieder zurück geändert wird.
Hinzu kommt noch, dass enzelne Wörter Teilwörter von anderen sein können. Also beispielsweise könnte ein Wortpaar Tür - Türklinke sein.
Kann mir hier irgendwer auf die Sprünge helfen, wie ich das elegant und effektiv lösen kann?
Elegant, effektiv und sogar effizient: Nimm strtr() in seiner zweiten Anwendungsform. Übergib die Wortpaare jeweils als zwei Einträge im Array, zuerst das längere als Key und das kurze als Wert und dann umgekehrt.
Lo!
Hi!
Nimm strtr() in seiner zweiten Anwendungsform. Übergib die Wortpaare jeweils als zwei Einträge im Array, zuerst das längere als Key und das kurze als Wert und dann umgekehrt.
Die Reihenfolge der Einträge im Array ist entgegen meiner ersten Annahme doch uninteressant, da die Funktion schon von selbst zuerst die längsten Übereinstimmungen berücksichtigt.
Lo!
Ich möchte nun einen Eingabe-String bearbeiten indem ich ein Wort jeweils durch seinen Partner ersetze. Und das in beide Richtungen....
Mein Problem ist nun dass ich irgendwie sicherstellen muss dass ein einmal ersetztes Wort nicht wieder zurück geändert wird.
Zur grundsätzlichen Herangehensweise: Mache einen Tausch im Dreieck, d.h. maskiere was Du ersetzen willst und ersetze danach nur das Maskierte.
Danke schon mal für die vielen Vorschläge/Ideen. Ich werde mich in ner ruhigen Minute mal dran setzen und daraus was (hoffentlich) funktionierendes basteln.
Hello,
Danke schon mal für die vielen Vorschläge/Ideen. Ich werde mich in ner ruhigen Minute mal dran setzen und daraus was (hoffentlich) funktionierendes basteln.
*grins*
Du musstest es doch nur noch als Programmcode ausformulieren, was ich Dir gepostet habe.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
Du musstest es doch nur noch als Programmcode ausformulieren, was ich Dir gepostet habe.
Warum so umständlich, wenn ein einzelner strtr()-Aufruf bereits alles Gewünschte macht?
Lo!
Hello,
Hi!
Du musstest es doch nur noch als Programmcode ausformulieren, was ich Dir gepostet habe.
Warum so umständlich, wenn ein einzelner strtr()-Aufruf bereits alles Gewünschte macht?
Das ist ja fein! Du meinst Example #2 strtr() example with two arguments?
Schön, wenn das funktioniert.
Welches Argument wird als erstes abgearbeitet?
Wie sieht es da aus mit der Einbettung eines Elements im anderen?
Muss ich nachher doch selber noch mal experimentieren...
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
Warum so umständlich, wenn ein einzelner strtr()-Aufruf bereits alles Gewünschte macht?
Das ist ja fein! Du meinst Example #2 strtr() example with two arguments?
Ja, so wie ich es schon geantwortet und nachgetragen hatte. strtr() in der zweiten Form mit dem Array ist überhaupt eine recht nützliche und anscheinend relativ unbekannte Funktion.
Schön, wenn das funktioniert.
Habs probiert, das Handbuch hat nicht geschwindelt.
Welches Argument wird als erstes abgearbeitet?
Das mit der längsten Übereinstimmung.
Wie sieht es da aus mit der Einbettung eines Elements im anderen?
Was schon bearbeitet wurde, wird nicht noch einmal berücksichtigt.
Lo!
Hello,
Welches Argument wird als erstes abgearbeitet?
Das mit der längsten Übereinstimmung.
Dann ist dieses StringTranslate wirklich eine geniale Funktion. Muss ich dringend nochmal 'mit spielen...
Nochmals danke für Deine Mühe.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg