nordlicht: Ersetzungen in einem String

Grüße euch!

ich habe einen String in dem ich IN MANCHEN Fällen was ersetzten möchte.
Beispiel (ok, ziemlich abstrakt, aber es geht nur ums Prinzip ;-)

$string = 'Hallo mein Name ist Hans'

kommt im String 'Hans', 'Sepp', 'Herbert' vor, sollen diese Wörter mit 'München'  ersetzt werden.

kommt im String 'Susi', 'Heidi', 'Iris' vor, sollen diese Wörter mit 'Hamburg' ersetzt werden.

so geht das weiter mit ca. 100*3 Ersetzungsmöglichkeiten.

  • Im String kommt entweder keiner dieser Namen vor oder genau einer (und nicht 2 oder mehr).
  • Jede Namenszuordnung ist eindeutig, also 'Hans' wird nur mit 'München' ersetzt. Man kann  die weitere Suche im Skript abbrechen.

Anhand dieser Rahmenbedingungen blick ich da nicht durch wie ich das am geschicktesten machen soll, vor allem damit da ich nicht unnötige IF-Abbfragen und str_replace in einer Schleife verwenden möchte, wenn die Ersetzung schon erfolgte. Oder unnötig aufgeblasene Arraydefinitionen.

In den Sinn kamen mir eben str_replace, mit dem man ja Arrays für Suche und Ersetzung übergeben kann. Dort müßte ich aber jede Stadt 3 mal definieren, z.B. jeweils 'München'  (für Hans, Sepp, Herbert). Ist also ev. unnötige Mehrfachdefinition?

oder eine Variante mit der switch-Anweisung?

oder auch per Zuordnung/Ersetzung mit einem assoziativen Array?
   "Hans"    => "München"
   "Sepp"    => "München"
   "Herbert" => "München"

  1. [latex]Mae  govannen![/latex]

    $string = 'Hallo mein Name ist Hans'

    kommt im String 'Hans', 'Sepp', 'Herbert' vor, sollen diese Wörter mit 'München'  ersetzt werden.

    In den Sinn kamen mir eben str_replace, [...]

    Was ist, wenn in der Zeichenkette "Hansestadt" vorkommt? str_replace wird daraus Münchenestadt machen.
    Ich würde hier preg_replace nehmen, um die Wortgrenzen definieren zu können..

    Stur lächeln und winken, Männer!
    Kai

    --
    var jQuery = $(hit);
    „Die Borg würden nicht mal Spaß verstehen, wenn sie einen Vergnügungspark assimiliert hätten!” (B'Elanna Torres)
    SelfHTML-Forum-Stylesheet
    1. Was ist, wenn in der Zeichenkette "Hansestadt" vorkommt? str_replace wird daraus Münchenestadt machen.
      Ich würde hier preg_replace nehmen, um die Wortgrenzen definieren zu können..

      Nein es kommt im String definitiv nur "Hans" vor. Es sollte also auch ohne Regex mit normalen Stringfunktionen machbar sein.

      1. [latex]Mae  govannen![/latex]

        Was ist, wenn in der Zeichenkette "Hansestadt" vorkommt? str_replace wird daraus Münchenestadt machen.
        Ich würde hier preg_replace nehmen, um die Wortgrenzen definieren zu können..

        Nein es kommt im String definitiv nur "Hans" vor. Es sollte also auch ohne Regex mit normalen Stringfunktionen machbar sein.

        Ok. Ich wollte nur auf diese Problematik aufmerksam machen, insbesondere, da manchmal versteckte Treffer vorkommen können, die man einfach nicht so leich sieht (wie bspw. vor einigen Jahren $somewhere kein Marschgepäck akzeptiert wurde, weil es in der Badword-Liste mit "Arsch" kollidierte.

        Stur lächeln und winken, Männer!
        Kai

        --
        var jQuery = $(hit);
        I am Pentium of Borg. Division is futile. You will be approximated.
        SelfHTML-Forum-Stylesheet
        1. Om nah hoo pez nyeetz, Kai345!

          Ok. Ich wollte nur auf diese Problematik aufmerksam machen, insbesondere, da manchmal versteckte Treffer vorkommen können, die man einfach nicht so leich sieht (wie bspw. vor einigen Jahren $somewhere kein Marschgepäck akzeptiert wurde, weil es in der Badword-Liste mit "Arsch" kollidierte.

          Meine allererste EBay-Bewertung sollte "Sogar die Post war schnell" enthalten.

          Matthias

          --
          1/z ist kein Blatt Papier.

  2. Tach!

    In den Sinn kamen mir eben str_replace, mit dem man ja Arrays für Suche und Ersetzung übergeben kann. Dort müßte ich aber jede Stadt 3 mal definieren, z.B. jeweils 'München'  (für Hans, Sepp, Herbert). Ist also ev. unnötige Mehrfachdefinition?

    Wenn nur München als Ersatz verwendet werden soll, dann kannst du ein Array für die Namen und München als String übergeben. Jedes Stadt muss dann mit einem eigenen str_replace() behandelt werden. Alles in einem Rutsch erledigen zu wollen, verlangt einzelne Zuordnungen. Bei str_replace() (und auch preg_replace() geht das aber nur in getrennten Arrays.

    oder auch per Zuordnung/Ersetzung mit einem assoziativen Array?
       "Hans"    => "München"
       "Sepp"    => "München"
       "Herbert" => "München"

    Ein assoziatives Array kannst du nur mit strtr() in seiner zweiten Variante verarbeiten. Auch sonst gibt es einige Unterschiede im Ersetzungsverhalten der beiden Funktionen.

    dedlfix.

    1. Wenn nur München als Ersatz verwendet werden soll, dann kannst du ein Array für die Namen und München als String übergeben. Jedes Stadt muss dann mit einem eigenen str_replace() behandelt werden.

      Das hört sich schonmal sehr brauchbar an! Aber welche Struktur verwende ich am besten außenrum?
      100 mal str_replace() hintereinander? Theoretisch kann man str_replace()-Überprüfungen ja schon beenden, wenn 1 Name ersetzt wurde, da mit Sicherheit keine weiteren mehr im String vorkommen.

      oder doch irgendwie mit switch?

      Ein assoziatives Array kannst du nur mit strtr() in seiner zweiten Variante verarbeiten.

      Könnte auch brauchbar sein, nur müßte ich hier ein Array mit 300 zeilen definieren, wobei für jede Stadt je 3 Arrayfelder definiert werden müßen. Ginge es auch "kürzer"?

      1. Tach!

        Wenn nur München als Ersatz verwendet werden soll, dann kannst du ein Array für die Namen und München als String übergeben. Jedes Stadt muss dann mit einem eigenen str_replace() behandelt werden.

        Das hört sich schonmal sehr brauchbar an! Aber welche Struktur verwende ich am besten außenrum?
        100 mal str_replace() hintereinander? Theoretisch kann man str_replace()-Überprüfungen ja schon beenden, wenn 1 Name ersetzt wurde, da mit Sicherheit keine weiteren mehr im String vorkommen.

        str_replace() bricht genauso wie strtr() nicht ab. Lediglich preg_replace() hat einen Limit-Parameter. Die ersten beiden kannst du auch durch eine Eigenkonstruktion ersetzen, die mit strpos() sucht und dann den String zerschneidet und wieder zusammensetzt. Ob das schneller ist, als str_replace() unnötigerweise den gesamten String durchsuchen zu lassen, wage ich zu anzuzweifeln. Unmöglich ist das aber nicht. Kommt sicher auch auf die Länge des zu bearbeitenden Strings an.

        oder doch irgendwie mit switch?

        Was willst du immer mit switch? switch wertet einen Ausdruck aus und verzweigt entsprechend der angegebenen Ergebnismöglichkeiten. Wo siehst du für deinen Fall eine Einsatzmöglichkeit für switch?

        Ein assoziatives Array kannst du nur mit strtr() in seiner zweiten Variante verarbeiten.
        Könnte auch brauchbar sein, nur müßte ich hier ein Array mit 300 zeilen definieren, wobei für jede Stadt je 3 Arrayfelder definiert werden müßen. Ginge es auch "kürzer"?

        Syntaktisch kürzer als mit den drei genannten Funktionen nebst dem dafür notwendigen Drumherum wirst du es nicht hinbekommen.

        dedlfix.

        1. Ok, ich hab Nägel mit Köpfen gemacht und ein Testskript verfasst. Es funktioniert, wäre das so in etwa in Ordnung? Das einzige was ich mir so als Laie denke: Ist es nötig aus der Schleife auszusteigen, wenn eine Ersetzung durchgeführt wurde, damit sie nicht umsonst noch weiterläuft?

            
          <?php  
          $searcharr = array(  
                         array ('Hans', 'Werner', 'Heini'),  
                         array ('Susi', 'Strolchi', 'Marie'),  
                         array ('Margot', 'Timo', 'Lisi'),  
                       );  
            
          $replacearr = array (  
                         'Muenchen',  
                         'Hamburg',  
                         'Berlin',  
                       );  
          						  
          $arrsize = count($replacearr);  
          $string = 'Hallo Strolchi';  
          for ($i = 1; $i <= $arrsize; $i++) {  
            $string = str_replace($searcharr[$i-1], $replacearr[$i-1], $string);  
          }  
          echo $string;  
          ?>  
            
            
            
          
          
          1. Tach!

            Ok, ich hab Nägel mit Köpfen gemacht und ein Testskript verfasst. Es funktioniert, wäre das so in etwa in Ordnung? Das einzige was ich mir so als Laie denke: Ist es nötig aus der Schleife auszusteigen, wenn eine Ersetzung durchgeführt wurde, damit sie nicht umsonst noch weiterläuft?

            Nochmal genau nachgefragt: Es kann ja nur einmal nach München ersetzt werden, aber kann danach immer noch vorkommen, dass ein anderer Teilstring nach Hamburg/Berlin/wasimmer ersetzt werden muss oder kann nach der ersten erfolgreichen Ersetzung komplett aufgehört werden? Wenn letzteres, dann liefert dir str_replace() in einem vierten Parameter die Anzahl der Ersetzungen zurück, was du als Abbruchkriterium verwenden kannst.

            $arrsize = count($replacearr);
            for ($i = 1; $i <= $arrsize; $i++) {
              $string = str_replace($searcharr[$i-1], $replacearr[$i-1], $string);

            $arrsize zu ermitteln gehört genauso wie das Setzen der Scheifenvariable zur Initialisierung des Schleifenvorgangs, also sollte es ebenfalls dort notieren werden (mit Komma getrennt). Weiterhin greifst du 0-basiert auf deine Arrays zu, dann ist es vorteilhafter, die Schleife bei 0 zu beginnen, den Wert direkt zu verwenden und nicht ständig eins abziehen zu müssen. Die Endebedingung ist dann nur < und nicht mehr <=.

            dedlfix.

            1. Es findet höchstens 1 Ersetzung statt, da maximal 1 Name vorkommen kann. Ich hab das Skript nach deinen Tips umgebaut, ich glaube das ist jetzt das Optimum ;-)

                
              <?php  
                $searcharr =  array (  
                                array ('Hans', 'Werner', 'Heini'),  
                                array ('Susi', 'Strolchi', 'Marie'),  
                                array ('Margot', 'Timo', 'Lisi'),  
                              );  
                $replacearr = array (  
                               'Muenchen',  
                               'Hamburg',  
                               'Berlin',  
                              );  
                $string = 'Hallo Hans';  
                $arrsize = count($replacearr);  
                for ($i = 0; $i < $arrsize; $i++) {  
                  $string = str_replace($searcharr[$i], $replacearr[$i], $string, $count);  
                  if ($count == 1) {break;}  
                }  
                echo $string;  
              ?>  
              
              
              1. [...] ich glaube das ist jetzt das Optimum ;-)

                Ich glaube das geht noch "schöner". Und zwar mit einem assoziativen Array:

                  
                <?php  
                      $replacements =  array (  
                            'Muenchen' => array ('Hans', 'Werner', 'Heini'),  
                            'Hamburg' => array ('Susi', 'Strolchi', 'Marie'),  
                            'Berlin' => array ('Margot', 'Timo', 'Lisi'),  
                      );  
                      $string = 'Hallo Hans';  
                      foreach($replacements as $replacement => $search){  
                            $string = str_replace($search, $replacement, $string, $count);  
                            if($count>0){  
                                  break;  
                            }  
                      }  
                      echo $string;  
                ?>  
                
                

                Sieht meiner Meinung nach sauberer aus, ist allerdings ungetestet.

                MfG
                bubble

                --
                If "god" had intended us to drink beer, he would have given us stomachs. - David Daye
                1. Sieht meiner Meinung nach sauberer aus, ist allerdings ungetestet.

                  ok, schaut super aus und funktioniert. Ich glaube, das kaufe ich jetzt endgültig - hast einen Cafe gut bei mir!
                  Danke an alle für ihre Tips.