Andreas Korthaus: einfacher regulärer Ausdruck

Hallo!

Irgendwie bekomem ich einen wirklich einfachen regulären Ausdruck nicht hin :-(

Ich will eine Preiseingabe prüfen, erlaubt sind entweder:

"12345"

oder

"12345,6789"

Die Anzahl der Stellen und  Nachkommastellen sind egal. Es geht nur darum, dass ich den Preis sicher in ein Computer-tagliches Format, also  12345.6789 umrechenn kann, indem ich einfach das eine Komma durch einen Punkt ersetz.

Jetzt will ich wie gesagt lediglich prüfen ob die Eingabe einem der obigen Formate entspricht:

/[0-9]*,?[0-9]+/

Ist es zwar nicht 100%ig, aber sehr einfach. Nur - aus welchem Grund ergibt die Eingabe von "12345.6789" TRUE?

Muss ich das verstehen? Selbst eine explizite Umwandlung in STRING hat nichts gebracht.

Am Anfang hatte ich sowas:

/[0-9]+(,[0-9]+)?/

Viele Grüße
Andreas

  1. Hio Andreas,

    Jetzt will ich wie gesagt lediglich prüfen ob die Eingabe einem der obigen Formate entspricht:

    /[0-9]*,?[0-9]+/

    Ist es zwar nicht 100%ig, aber sehr einfach. Nur - aus welchem Grund ergibt die Eingabe von "12345.6789" TRUE?

    weil du nicht definierts an welcher Stelle deiner Zeichenkette das Muster auftretten muss, insofern erfüllt die 1. Ziffer schon deinen regulären Ausdruck

    /[1]*,?[0-9]+$/ würde es schon eher treffen.
    Dabei steht ^ für den Anfang deiner Zeichenkette (der Ausdruck muss also damit beginnen) und das $ für das Ende (der Ausdruck muss alos damit enden).
    Wobei dann der Punkt selber nicht zulässig wäre, du aber genau auf dieses Format kommen willst. Oder anders gesagt, gibt jmd weil für ihn gewohnt den Preis mit dem Punkt an (mayb weil us-amerkianer) akzetierst du es nicht obwohl ja eigentlich zulässig (nur so als idee)

    Muss ich das verstehen? Selbst eine explizite Umwandlung in STRING hat nichts gebracht.

    klar nicht, s.o. ^^
    möglich wäre auch folgendes (ungetestet)

    if ($wert == floatval($wert))

    gl & hf

    Thorsten


    1. 0-9 ↩︎

    1. Hallo!

      weil du nicht definierts an welcher Stelle deiner Zeichenkette das Muster auftretten muss, insofern erfüllt die 1. Ziffer schon deinen regulären Ausdruck

      Ah, wie dumm von mir ;-)

      Wobei dann der Punkt selber nicht zulässig wäre, du aber genau auf dieses Format kommen willst. Oder anders gesagt, gibt jmd weil für ihn gewohnt den Preis mit dem Punkt an (mayb weil us-amerkianer) akzetierst du es nicht obwohl ja eigentlich zulässig (nur so als idee)

      Das stiftet nur Verwirrung. Beu uns gibtes ja Zahlen wie 3.800,55, oder 3.899, wie unterscheide ich dass dann von 3,899, wenn ein Amerikaner 3.899 schreibt? Das darf man nicht. Ein Amerikaner kann aber das Zahllenformat ändern, udn dann geht 3.899, dafür 3,899 nicht mehr, denn da ist das Problem genau umgekehrt.
      (Preise können 10 Nachkommastellen haben!)

      if ($wert == floatval($wert))

      Das Funktioniert wohl nicht mit "," oder? Das ist mir orgendwei nicht so angenehm.

      Ich verwende jetzt:

      /[1]+(,[0-9]+)?$/

      Das müsste doch ausschließelich auf beide Formate passen:

      3456 und 3456,789

      oder? Es _scheint_  zumindest zu funktionieren.

      Vielen Dank!

      Grüße
      Andreas


      1. 0-9 ↩︎

  2. gruss Andreas,

    Die Anzahl der Stellen und  Nachkommastellen sind egal. Es geht
    nur darum, dass ich den Preis sicher in ein Computer-tagliches
    Format, also  12345.6789 umrechenn kann, indem ich einfach das
    eine Komma durch einen Punkt ersetz.

    Jetzt will ich wie gesagt lediglich prüfen ob die Eingabe einem
    der obigen Formate entspricht:

    /[0-9]*,?[0-9]+/

    es gibt noch mehr moegliche formatierungen, ...

    ... die sich mit einem "einfachen regulaeren ausdruck"
       nicht erschlagen lassen;

    in javascript habe ich mal versucht das problem zu loesen,
       indem ich die methode "String.forceToNumber()" schrieb;

    diese konvertiert alle dezimalen zahlen-strings, deren
       formatierungen "human readable" sind in die entsprechenden
       fliesskommazahlen - unsinnige formatierungen werden auch
       akzeptiert, aber deswegen heisst die methode ja "forceToNumber";

    der js-code ist kommentiert und hilft Dir vielleicht weiter:

    String.prototype.forceToNumber = function() {
        var content = this;
        var posDot = content.lastIndexOf(".");   // letzte position von "." im string;
        var posComma = content.lastIndexOf(","); // letzte position von "," im string;
        var comma = "";
        var regExpValue = /\d+/g;
        var regExpMatch = null;
        if ((posDot >= 0) || (posComma >= 0)) {  // kommen "." oder "," im string ueberhaupt vor ?
            if (((content.split(".")).length == 2) && ((content.split(",")).length == 2)) { // falls "." als auch "," den string in genau zwei teile zerlegen koennen, ...
                content = content.split((posDot>posComma) ? (".") : (",")); //... nimm an, dass der kommaseparator dasjenige zeichen ist, welches an letzter stelle steht und teile den string genau dort;
            } else if (((content.split(".")).length == 2) && ((content.split(",")).length != 2)) { // entzweit nur "." den string, ...
                content = content.split("."); //... dann lege dieses zeichen als kommaseparator fest und teile den string genau dort;
            } else if (((content.split(".")).length != 2) && ((content.split(",")).length == 2)) { // entzweit nur "," den string, ...
                content = content.split(","); //... dann nimm dieses zeichen als kommaseparator und teile den string genau dort;
            } else {
                content = new Array(content); // anderenfalls handelt es sich um kein fuer diese methode relevantes zahlenformat;
            }
        } else {
            content = new Array(content); // "." bzw. "," sind ueberhaupt nicht bestandteil der (formatierten?) zahl;
        }
        for (var i=0;i<content.length;i++) { // nimm dir die eintraege in "content" vor - (minimal 1 eintrag ohne kommaseparator / maximal 2 eintraege mit kommaseparator);
            regExpMatch = content[i].match(regExpValue); // loese jede zahl die Du findest einzeln aus dem jeweiligen eintrag heraus;
            content[i] = ""; // leg' den default-wert fuer den jeweiligen eintrag als leer-string fest;
            if (regExpMatch) { // schau nach, ob im jeweiligen eintrag ueberhaupt zahlen vorhanden waren, ...
                for (var k=0;k<regExpMatch.length;k++) { // ... wenn ja, dann nimm Dir jede zahl einzeln vor, ...
                    content[i] += regExpMatch[k]; // ... und fuege sie dem aktuellen default-wert hinzu;
                }
            }
        }
        return parseFloat((content.length == 1) ? (content[0]) : (content[0] + "." + content[1]));
     // gab es nur einen eintrag, dann nimm eben nur diesen,
     // gab es zwei eintraege, dann verbinde diese vorher mit einem "." -
     // konvertiere das gesamtergebnis auf jeden fall in eine fliesskommazahl;
    };
    //  var myNumber = "1 340 333,5678"; myNumber.forceToNumber() = 1340333.5678;
    //  var myNumber = "1,340,333.5678"; myNumber.forceToNumber() = 1340333.5678;
    //  var myNumber = "1.340,333.5678"; myNumber.forceToNumber() = 1340.3335678;
    //  var myNumber = "1,340,333,5678"; myNumber.forceToNumber() = 13403335678;
    //  var myNumber = "1,g40,3j3,5k7m"; myNumber.forceToNumber() = 1403357;
    //  var myNumber = "1.g40,3j3.5k7m"; myNumber.forceToNumber() = 140.3357;
    //  var myNumber = "1.g40,3j3,5k7m"; myNumber.forceToNumber() = 1.403357;
    //  var myNumber = "yy.mm.dd"; myNumber.forceToNumber() = NaN;

    by(t)e by(t)e - peterS. - pseliger@gmx.net

    --
    sh:| fo:) ch:? rl:| br:& n3:} n4:# ie:| mo:{ va:| de:[ zu:] fl:) ss:) ls:& js:)

    1. Hi!

      /[0-9]*,?[0-9]+/

      es gibt noch mehr moegliche formatierungen, ...

      ... die sich mit einem "einfachen regulaeren ausdruck"
         nicht erschlagen lassen;

      Wie in [pref:t=52485&m=289627] bechrieben, noch nichtmal ich als Mensch könnte mit Sicherheit sagen was der sich dabei gedacht hat.

      Meint er mit 3.456 jetzt 3456 oder 3,456? Die einzige sichere Möglichkeit ist die eindeutige Festlegung des Formats, und dem Anwender verschiedene Preisformate zur Auswahl zu geben.

      Bei mir darf unter keine Umständen der Preis falsch verstanden werden, daher gebe ich lieber einmal zu oft ne Fehlermeldung aus, als einmal zu wenig.
      Trotzdem Dank!

      Grüße
      Andreas

  3. Hallo Andreas,

    "12345"

    oder

    "12345,6789"

    [...]

    /[0-9]*,?[0-9]+/

    Sinnvoller ist hier:

    /^\d+(?:,\d+)?$/

    "Eine Zahl, gefolgt von einem optionalen Teil. Dieser
    optionale Teil darf ein Komma, gefolgt von einer weiteren
    Zahl sein".

    Gruesse,
     CK

    --
    http://cforum.teamone.de/
    http://wishlist.tetekum.de/
    If God had meant for us to be in the Army, we would have been born with green, baggy skin.