Andreas Korthaus: Zahlenformat umwandeln

Hallo!

Es gibt ja verschiedene Zahlenformate für Preise, so z.B.

in USA 123,456.00 oder 123456.00 oder 123,456 oder 123456
bei uns 123.456,00 oder 123456,00 oder 123.456 oder 123456

Alle diese Formate könnten ja eingegeben werden, aber Programmiersprachen verstehen ja bekanntlich nur ein Format: 123456.00

Ich habe das mal so probiert:

function php_preis($eingegebener_preis){
    if (preg_match("/.[0-9]{1,2}$/",$eingegebener_preis)) {
     return str_replace(",","",$eingegebener_preis);
 }
 else {
     return str_replace(",",".",str_replace(".","",$eingegebener_preis));
 }
}

Das funktioniert meines Erachtens, aber kann ich mich darauf auch verlassen? Was habe ich vieleicht nicht bedacht? Hat es Sinn  mit Hilfe von RegExprs auch Währungsangaben abzufangen, also auch wenn jemand dahinter oder davor noch EUR, €, USD, $ ... eingibt? Oder sollte ich mich azf ibige Funktion beschränken und vielleicht vorher noch Zeichen außer Zahlen und "," und "." suchen, udn sofort eine Fehlermeldung ausgeben?

Das wichtigste ist das keine fehlerhaften Eingaben in die Datenbank gelangen, wie stelle ich das am sinnvollsten sicher?

Viele Grüße
Andreas

  1. Hallo!

    selber!

    in USA 123,456.00 oder 123456.00 oder 123,456 oder 123456

    stimmt, aber gute Typografie stammt aus Deutschland oder der Schweiz ,-)

    Ich habe das mal so probiert:

    function php_preis($eingegebener_preis){
        if (preg_match("/.[0-9]{1,2}$/",$eingegebener_preis)) {
         return str_replace(",","",$eingegebener_preis);
    }
    else {
         return str_replace(",",".",str_replace(".","",$eingegebener_preis));
    }
    }

    verstehe ich den Ausdruck richtig?:
    1. Du suchst nach einem String, der einen Punkt und danach ein oder zwei Ziffern enthält (ami-Screibweise) und löscht dann das Komma (aber nur, sofern vorhanden!)
    hmm...
    sieht gut aus. aber was ist, wenn der User versehentlich oder aus terroristischen Motiven drei nachkomma(nachpunkt)stellen schreibt?
    wird dann nicht aus: 150,000,000.000 (für hundertfünfzig-komma-null-millionen) eine: 150.000.000000 ?

    2. ist 1. nicht der Fall gehst Du wohl von deutscher Buchhalter-Schreibweise aus und löscht den Punkt (als tausender-Trenner) und ersetzt dann das Komma durch einen Punkt.
    hmm...
    ich glaube das würde gehen - wenn der User brav ist und das tut, was Du willst.
    aber was ist, wenn er nur mehrere Kommas eingibt, z.B.: 150,000,000 für hundertfünfzigmillionen? dann kommst Du nicht in Fall 1. rein, oder? Du erhälst also: 150.000.000

    Was habe ich vieleicht nicht bedacht? Hat es Sinn [...] Währungsangaben abzufangen, also auch wenn jemand dahinter oder davor noch EUR, €, USD, $ ... eingibt?

    Ich glaube schon - wichtig finde ich vor dem Abschicken der Zahl eine Kontrollausgabe: "das haben Sie eingegeben: wolle Sie das senden?"

    Ich habe die Ersetzungen mal so gemacht (fängt auch alle nicht Zahlen ab, bzw. löscht sie aus dem String) allerdings nicht so elegant wie Du und in JavaScript:

    //Preiseingaben in korrekte Float-Zahl umwandeln; Zahlen mit Punkt oder Komma aktzeptieren
    function preis_format(preisilein)
    {
     var string;
     preis=preisilein.toString();

    //wenn ein Preis mit Komma eingegeben wurde, dieses in Punkt umwandeln
     if(preis.indexOf(',')!=-1)
     {
      string='';
      string += preis.substring(0, preis.indexOf(','));
      string += '.';
      string += preis.substring(preis.indexOf(',')+1, preis.indexOf(',')+3);
     }

    //wenn ein Preis mit Punkt eingegeben wurde, auf zwei Nachkommastellen begrenzen
     else if(preis.indexOf('.')!=-1){
      string=preis.substring(0, preis.indexOf('.')+3);
     }
     else if(preis.indexOf('.')==-1 && preis.indexOf(',')==-1){
      string=preis+'.00';
     }

    //preis-String in Zahl umformen
     preis_float=parseFloat(string);
     preis=Math.round(preis_float*100)/100;
    }

    bei massivem Blödsinn gibt das System NaN zurück - das kannst Du ja vor der Datenbank noch abfragen.

    /******* dies ist nicht direkt Dein Problem, hier kann ich wieder eine Float-Zahl eingeben und einen deutschen Preis daraus machen ******************/
    //Ausgabepreis mit zwei Nachkommastellen formatieren
    function ausgabe(preis)
    {
     var string;

    //Float-Wert mit drei Nachkommastellen (ohne den Euro-Pfennig-Wert zu ändern)
     ausgabe=preis+0.001;

    //zurück in String, um mit Komma formatieren zu können
     ausgabe=ausgabe.toString();
     string='';
     string += ausgabe.substring(0, ausgabe.indexOf('.'));
     string += ',';
     string += ausgabe.substring(ausgabe.indexOf('.')+1, ausgabe.indexOf('.')+3);

    return string;
    }

    mit dieser Funktion gebe ich den formatierten Preis immer zurück und der User kann sehen ob er das richtige eigegeben hat

    Gruß, Andreas

    1. Hi!

      function php_preis($eingegebener_preis){
          if (preg_match("/.[0-9]{1,2}$/",$eingegebener_preis)) {
           return str_replace(",","",$eingegebener_preis);
      }
      else {
           return str_replace(",",".",str_replace(".","",$eingegebener_preis));
      }
      }
      verstehe ich den Ausdruck richtig?:

      1. Du suchst nach einem String, der einen Punkt und danach ein oder zwei Ziffern enthält (ami-Screibweise) und löscht dann das Komma (aber nur, sofern vorhanden!)
        hmm...
        sieht gut aus. aber was ist, wenn der User versehentlich oder aus terroristischen Motiven drei nachkomma(nachpunkt)stellen schreibt?
        wird dann nicht aus: 150,000,000.000 (für hundertfünfzig-komma-null-millionen) eine: 150.000.000000 ?

      Ja, aber am bsten fange ich für solche Dinge den return-Wert vorher nochmal ab udn prüfe mit nem regulären Ausdruck ob es korrekt ist, wenn nicht gibts nen Fehler, ich kann ja nicht jede Doofheit der User Manuell abfangen ;-)

      1. ist 1. nicht der Fall gehst Du wohl von deutscher Buchhalter-Schreibweise aus und löscht den Punkt (als tausender-Trenner) und ersetzt dann das Komma durch einen Punkt.
        hmm...
        ich glaube das würde gehen - wenn der User brav ist und das tut, was Du willst.
        aber was ist, wenn er nur mehrere Kommas eingibt, z.B.: 150,000,000 für hundertfünfzigmillionen? dann kommst Du nicht in Fall 1. rein, oder? Du erhälst also: 150.000.000

      Auch richtig. Und da auch das eine definitiv Fehlerhafte Usereingabe ist wird das auch am Ende abgefangen, wenn der endgültige Wert nicht mit /[0-9]+.[0-9]{2}/ übereinstimmt.

      Was habe ich vieleicht nicht bedacht? Hat es Sinn [...] Währungsangaben abzufangen, also auch wenn jemand dahinter oder davor noch EUR, €, USD, $ ... eingibt?
      Ich glaube schon - wichtig finde ich vor dem Abschicken der Zahl eine Kontrollausgabe: "das haben Sie eingegeben: wolle Sie das senden?"

      Das will ich vermeiden, nur wegen einer Zahl einen extra-Schritt einbauen, daher brauche ich eine Prüfung die entweder 100%ig das richtige umwandelt oder im Zweifel einen Fehler ausgibt. Die Währungen werde ich auch mal filtern und entfernen, da eine Währung vorgeschreiben ist, z.B. USD, kann ich ja noch prüfen /(USD|$) ?(.*) ?(USD|$)/ sowas der Art. Und wenn irgendwelche anderen Zeichen gefunden werden => FEHLER!

      Ich habe die Ersetzungen mal so gemacht (fängt auch alle nicht Zahlen ab, bzw. löscht sie aus dem String) allerdings nicht so elegant wie Du und in JavaScript:

      [...]

      nicht schlecht! Aber ich denke mit Regulären Ausdrücken ist das in PHP etwas einfacher zu machen! Danke für die Tipps!

      Grüße
      Andreas