PeTaGeh: Reguläre Ausdrücke

Moinsen,

ich hab da mal ein Problem mit einem regulären Ausdruck. Ich möchte einen Preis in einer Ausgabevariablen ändern von englischem zu deutschem Format:

$test = 'bla bla bla bla 1,565.43€ bli bli bli 599.77€ blo blo blo';
  $test_1 = ereg_replace("([0-9]+),*([0-9]+).([0-9]+€)", "\1.\2,\3", test);
  echo '<p>'.$test_1.'</p>';

Gibt mir nicht das Resultat, das ich erwarte:
bla bla bla bla 1.565,43€ bli bli bli 59.9,77€ blo blo blo

Er sollte eigentlich :
bla bla bla bla 1.565,43€ bli bli bli 599,77€ blo blo blo

ausgeben. Was stimmt mit meinem rex.exp nicht?

Gruss, Peter

--
If kids had been influenced by Pacman, they'd be jumping around in dark rooms eating strange pills and listening to monotonous music these days.
  1. Zwischen den zwei Neunen wird keinmal das Komma gefunden und mit einem Punkt ersetzt.

    Wenn Du das abstellst, wirst Du aber merken, daß der zweite Preis dann gar nicht mehr auf das Suchmuster paßt.

  2. ([0-9]+),*([0-9]+).([0-9]+€)

    Das kann schonmal insofern nicht hinhauen, als dass du zum einen mit ,* "beliebig viele Kommas" verlangst (du möchtest aber beliebig ein-, zwei- oder dreistellige Zahlen mit einem Komma dahinter) und zum zweiten zwischen der zweiten und dritten Zahl mit dem . ein beliebiges Zeichen zulässt (du möchtest einen Punkt haben).

    Ich täte es (mit PCRE-Mustern) einfacher probieren, zuerst:

    \D([0-9]{1,3}),(([0-9]{3})+([,.][0-9,.]+)?)\s*€) -> $1.$2

    Und anschließend:

    \D([0-9]{1,3}).([0-9]{2}\s*€) -> $1,$2

    1. Moinsen,
      Dank erstmal für die guten Lösungsansätze. Haben mich in die richtige Bahn geschoben.
      Bei Gonzo hatte es mit den grösseren Zahlen plötzlich irgendwie nicht mehr so richtig hingehauen.
      Ich hab jetzt eine Lösung, die befriedigend ist:

      $test = 'bla. bla.bla bla 1,565.43€ bli bli bli 599.77€ blo blo blo 0.56€ blu blu blu 1,459,232.45€</a>';
        $test_1 = preg_replace("/(([0-9]{1,3})(,([0-9]{3}))*).([0-9]{2}\x80)/e","strtr('\1', ',', '.') . ',' . '\5'",$test);

      vielen Dank nochmal! :D

      ([0-9]+),*([0-9]+).([0-9]+€)

      Das kann schonmal insofern nicht hinhauen, als dass du zum einen mit ,* "beliebig viele Kommas" verlangst (du möchtest aber beliebig ein-, zwei- oder dreistellige Zahlen mit einem Komma dahinter) und zum zweiten zwischen der zweiten und dritten Zahl mit dem . ein beliebiges Zeichen zulässt (du möchtest einen Punkt haben).

      Ich täte es (mit PCRE-Mustern) einfacher probieren, zuerst:

      \D([0-9]{1,3}),(([0-9]{3})+([,.][0-9,.]+)?)\s*€) -> $1.$2

      Und anschließend:

      \D([0-9]{1,3}).([0-9]{2}\s*€) -> $1,$2

      Gruss, Peter

      --
      If kids had been influenced by Pacman, they'd be jumping around in dark rooms eating strange pills and listening to monotonous music these days.
      1. gudn tach!

        $test_1 = preg_replace("/(([0-9]{1,3})(,([0-9]{3}))*).([0-9]{2}\x80)/e","strtr('\1', ',', '.') . ',' . '\5'",$test);

        huch, hab dein posting irgendwie uebersehen. die von mir gegebene loesung ist dasselbe in gruen; mit kleinen unterschieden:

        1. wenn du etwas wert auf geschwindigkeit legst, empfehle ich dir die von mir genannte methode via _callback, da das i.a. von php verarbeitet wird. zumindest war das mal so, vielleicht wurde das mittlerweile verbessert.

        2. das punkt-problem hast du noch immer nicht geloest. ein punkt muss bei regexp normalerweise mit backslash maskiert werden, um seine literale bedeutung zu erhalten. ansonsten bedeutet er "beliebiges zeichen (u.u. ausser zeilenumbruch)".

        prost
        seth

    2. gudn tach!

      Ich täte es (mit PCRE-Mustern) einfacher probieren,

      ich auch, aber nicht wie wie Gonzo, weil da z.b. zahlen am zeilenanfang ignoriert und lange zahlen falsch ersetzt wuerden.

      wenn denn einfach alle punkte und kommas vertauscht werden sollen, dann kannst du das mittels
      preg_replace_callback und strtr bewerkstelligen. etwa so (ungetestet):

      $str = preg_replace_callback('(?<![.,0-9])\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?\s*€',  
        create_function(  
          '$matches',  
          'return strtr($matches[0],".,",",.");'  
        ), $str  
      );
      

      besser denn punkte als zifferngruppierungszeichen erachte ich uebrigens schmale (oder wenigstens geschuetzte normale) leerzeichen, wie sie ISO-maessig vorgesehen sind.

      prost
      seth