Nick: Suchen und Ersetzen mittels RegExp - Positives Lookbehind

Hallo,

ich habe folgenden Test-String, auf den ich ein bedingtes "Suchen und Ersetzen" mittels RegExp anwenden möchte:

Der Test-String "wert" lautet:

wert = "Haus mit Garage, Villa mit Pool, Laube mit Fenster, aber immer mit Strom";

Suchen mit Bedingung:

Suche in "wert" nach dem Wort "mit", dem eines der Wörter Haus, Villa, Laube (gefolgt von einem Leerzeichen) vorausgeht.

Ersetzen:

Ersetze in diesem Fall das Wort "mit" durch das Wort "ohne".

Ergebnis soll sein:

"Haus ohne Garage, Villa ohne Pool, Laube ohne Fenster, aber immer mit Strom"

Das letzte "mit" im Test-String soll also nicht ersetzt werden, weil hier die Bedingung nicht erfüllt ist, d.h. keines der Wörter "Haus", "Villa" oder "Laube" vorausgeht.

------------------------------------------------------------------------------------------------------------------------------------------------

Das ist wohl das Problem, das man mit einem "Positiven Lookbehind" angehen würde, den es in Javascript aber nicht zu geben scheint.

Ich habe das bisher so gelöst, würde mich aber nicht wundern, wenn das nicht auch schlanker ginge:

wert = "Haus mit Garage, Villa mit Pool, Laube mit Fenster, aber immer mit Strom";

reg = /\bHaus mit\b|\bVilla mit\b|\bLaube mit\b/;

while (reg.test(wert))
{

wert = wert.replace(/\bHaus mit\b/,'Haus ohne');
wert = wert.replace(/\bVilla mit\b/,'Villa ohne');
wert = wert.replace(/\bLaube mit\b/,'Laube ohne');

}

Wer hat einen Tipp ?

Mfg Nick

  1. gruss Nick,

    ...
    Ich habe das bisher so gelöst, würde mich aber nicht wundern,
    wenn das nicht auch schlanker ginge:
    ...
    ...
    Wer hat einen Tipp ?
    ...

    probier es doch mal mit einer gruppe alternativer ausdruecke und
    deren gespeicherter referenz beim ersetzen:

    /*  
      code bitte in die [link:http://jconsole.com/@title=[jconsole\]] pasten  
    */  
    var str = "Haus mit Garage, Villa mit Pool, Laube mit Fenster, aber immer mit Strom";  
      
    var regXImmobilieMit = (/(Haus|Villa|Laube)(\s+)mit/g);  
      
    str = str.replace(regXImmobilieMit, "$1$2ohne");  
      
    print(str); // alert(str);
    

    so long - peterS. - pseliger@gmx.net

    --
    »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
    Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
    ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]
    1. Genau das ! Herzlichen Dank, PeterS !

      // var regXImmobilieMit = (/(Haus|Villa|Laube)(\s+)mit/g);

      P.S.

      Die den RegExp umschliessende Klammer darf ich doch konsequenzenlos entfernen, oder ? Jedenfalls hat es bei meinen test keine Probleme gegeben ...

      "Meins" sieht jetzt so aus:

      ---------------------------------------

      reg = /(Haus|Villa|Laube)(\s)mit/;

      while (reg.test(wert))
      wert = wert.replace(reg,'$1$2ohne');

      ---------------------------------------

      Mfg Nick

      1. hallo again Nick,

        // var regXImmobilieMit = (/(Haus|Villa|Laube)(\s+)mit/g);
        Die den RegExp umschliessende Klammer darf ich doch konsequenzenlos
        entfernen, oder ? ...

        ja, aber den *global flag* solltest Du nicht anfassen - der erspart
        Dir doch die iteration ueber [while] - hast Du das von mir gepostete
        script ueberhaupt in seiner gesamtheit ausprobiert?

        "Meins" sieht jetzt so aus:


        reg = /(Haus|Villa|Laube)(\s)mit/;

        // noe - dann doch eher so wie von mir vorgegeben:  
           var reg = (/(Haus|Villa|Laube)(\s+)mit/g);  
          
        // meinetwegen auch noch wie von Dir gewuenscht:  
        // var reg = /(Haus|Villa|Laube)(\s)mit/g;  
          
           var wert = "Haus mit Garage, Villa mit Pool, Laube mit Fenster, aber immer mit Strom";  
          
        /* naechste zeile ist dann ueberflusssig:  
        
        > while (reg.test(wert))  
        > */  
        
           wert = wert.replace(reg,'$1$2ohne');  
          
           alert(wert);
        

        ...

        so long - peterS. - pseliger@gmx.net

        --
        »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
        Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
        ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]
        1. Hallo PeterS.,

          herzlichen Dank, das Du für mich nochmal so weit runtergescrollt hast ...

          ... selbstverständlich habe ich - wenn mir schon jemand so konkret unter die Arme greift - das Script ausprobiert ...

          ... trotzdem hätte ich natürlich gerne gewußt, welche Bedeutung die den RegExp umschließende Klammer hat. Sparen - wo immer möglich !

          In dem betreffenden Selfhtml-Artikel zu $[1..9]

          [http://de.selfhtml.org/navigation/suche/index.htm?Suchanfrage=regexp]

          habe ich auch schon vorab von der Möglichkeit gelesen, mein Problem auf diesem Weg zu lösen:

          Allerdings habe ich mich hier von den zwei Anmerkungen abschrecken lassen:

          "Seit der JavaScript-Version 1.5 gilt das Auslesen der Treffer geklammerten Ausdrücke über RegExp.$1, RegExp.$2 und so weiter als veraltet. In der Praxis steht allerdings nur bei der im Beispiel verwendeten Methode exec() eine Alternative zur Verfügung. Näheres entnehmen Sie bitte der Beschreibung von exec()."

          "Safari und Konqueror bilden eine Ausnahme: Bei den Methoden match() und replace() werden RegExp.$1 und folgende Eigenschaften nicht gefüllt. Im obigen Beispiel gelingt das Auslesen des Teiltreffers in diesen Browsern daher nicht. Es müsste z.B. ausdrücklich exec() ausgeführt werden, um an die Teiltreffer zu kommen."

          Bedeutet das, dass das Auslesen von $1,$2 etc. in meinem Beispiel im Safari und Konqueror nicht funktioniert ???

          Falls Du nochmals vorbeikommst: Dank im Voraus

          Gruß aus HH-Ottensen nach HH-?

          Mfg Nick