Jojo: /RegExp "Nicht der String"

Hallo Leute

Ich bin wieder mal am Schwitzen mit RegExps :-/

Es geht um Folgendes:
Ein String:
{gettext msgid="irgend ein Text, der auch sowas "} '} enthalten kann ! "}

So...

Ich möchte das nun ersetzen.

Das Suchmuster, das ich mir ausgedacht habe lautet in Worten ungefair so:
Zuerst : {gettext msgid="
Dann : _alles_ AUßER dieser String "}
Zuletzt : "}

Das hört sich leider viel viel zu leicht an...

Mein Problem ist, dass ich nicht weiß, wie ich _Zeichenketten_ negieren kann (wenn man das so nennen kann)

Ich habe schon sehr sehr viel ausprobiert, bin aber leider zu keinem Ergebnis gekommen.

Hier mal meine Versuche für die RegExps:
'/{gettext msgid="((^(\"}))*)"}/Umi'
'/{gettext msgid="([^"}]*)"}/Umi'
'/{gettext msgid="([1]*)"}/Umi'

Das sind zwar nicht alle, aber ich denke meine Versuche kommen rüber :-)

BTW:
Ich verwende preg_replace();

Gruß
Jojo


  1. \"} ↩︎

  1. Tag Jojo.

    {gettext msgid="irgend ein Text, der auch sowas "} '} enthalten kann ! "}
    Ich möchte das nun ersetzen.

    Was genau? Willst du alles, was zwischen den Doublequotes steht, haben? Dann sollte

    $test = "{gettext msgid='irgend ein Text, der auch sowas \'} \'} enthalten kann ! '}";  
    echo preg_replace('/^{gettext msgid=(.+)}$/', '$1', $test);
    

    helfen.

    Siechfred

    1. Hi Siechfred,

      Was genau? Willst du alles, was zwischen den Doublequotes steht, haben? Dann sollte

      $test = "{gettext msgid='irgend ein Text, der auch sowas '} '} enthalten kann ! '}";

      echo preg_replace('/^{gettext msgid=(.+)}$/', '$1', $test);

      
      >   
      > helfen.  
        
      Nein, das wird so nicht gehen - zumindest dann nicht, wenn es über das gegebene Beispiel hinausgeht. So wie das aussieht, handelt es sich hier um eine Art Template Ersetzungs Funktion - da können die Platzhalter natürlich beliebig oft vorkommen, z.B:  
        
      `$string = "Ein {gettext msgid='langer'} Text, mit {gettext msgid='vielen'} Platzhaltern";`{:.language-php}  
        
      Da reguläre Ausdrücke standardmäßig „gefräßig” sind, würde obiger Programmcode von dir `"'langer'} Text, mit {gettext msgid='vielen'"`{:.language-php} zurückliefern.  
        
      Eine simple Möglichkeit, wäre den RegEx auf Ungreedy (ungefräßig) zu schalten, mittels dem Modifier U - aber dann wäre es noch immer nicht möglich die ein " oder ' zu escapen um ihm die Wirkung des Beenden des Strings zu entziehen.  
        
      Um das Problem zu lösen: Ich habe mir gerade noch mal entsprechende Seite im [PHP Manual](http://de2.php.net/manual/en/reference.pcre.pattern.syntax.php) angesehen, ich dachte eigentlich spontan an [Conditional Subpatters](http://de2.php.net/manual/en/reference.pcre.pattern.syntax.php#regexp.reference.conditional) und dass das damit doch irgendwie zu lösen sein müsste. Allgemein, sieht so etwas so aus: (?(condition)yes-pattern|no-pattern)  
        
      Für diesen Fall:  
      (?(?=[^\\\\])[^']|\\\\.)\*  
      Wenn ein Zeichen kommt, dass kein Backslash ist,  
                 dann darf dieses eine Zeichen genau einmal vorkommen  
                     sonst kommt der Backslah und ein beliebiges (somit escaptes) Zeichen  
        
      Ich hoffe, dass ich es richtig im Kopf habe, dass man vier Backslashs schreiben muss, um einen in die RegEx Machine zu bekommen - einmal müss für PHP escaped werden und einmal für PCRE...  
        
      Alles in allem also:  
        
      ~~~php
      $string = "Ein {gettext msgid='langer \'} komplizierter'} Text, mit {gettext msgid='vielen'} Platzhaltern";  
      echo preg_replace("/\{gettext msgid='((?(?=[^\\\\]).|\\\\.)*)'\}/U", "$1", $string);
      

      Da ich mir jetzt gerade doch nicht so sicher war, obs funktioniert, hab ichs mal getestet (etwas Korrektur war auch noch nötig ;-) und jetzt klappts, die Ausgabe von obigem Beispiel sieht so aus:

      Ein langer '} b Text, mit vielen Platzhaltern

      Vielleicht ein kleiner Nachteil: Hier lässt sich jedes Zeichen escapen und es klappt noch nicht wirklich, einen Backslash zu escapen (zumindest nicht am Ende eines Strings) - aber es steht anderen ja frei, meinen Code zu korrigieren ;-)

      MfG, Dennis.

      --
      Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
      Die FlatBox 0.3 mit Dokumentation ist da!
      Die Stoßstange ist aller Laster Anfang! (Häfft)