Was ist der sauberste und effektivste Weg, um Dezimalzahlen in JavaScript zu validieren?
Bonuspunkte für:
- Klarheit. Die Lösung sollte sauber und einfach sein.
- Plattformübergreifend.
Testfälle:
01. IsNumeric('-1') => true
02. IsNumeric('-1.5') => true
03. IsNumeric('0') => true
04. IsNumeric('0.42') => true
05. IsNumeric('.42') => true
06. IsNumeric('99,999') => false
07. IsNumeric('0x89f') => false
08. IsNumeric('#abcdef') => false
09. IsNumeric('1.2.3') => false
10. IsNumeric('') => false
11. IsNumeric('blah') => false
javascript
validation
numbers
Michael Haren
quelle
quelle
jQuery.isNumeric
Utility-Funktion eingeführt: api.jquery.com/jQuery.isNumericjQuery.isNumeric
wird den siebten Testfall des OP nicht bestehen (IsNumeric('0x89f') => *false*
). Ich bin mir jedoch nicht sicher, ob ich diesem Testfall zustimme.Antworten:
@ Joels Antwort ist ziemlich nah, aber sie wird in den folgenden Fällen fehlschlagen:
Vor einiger Zeit musste ich eine
IsNumeric
Funktion implementieren , um herauszufinden, ob eine Variable einen numerischen Wert enthielt, unabhängig von ihrem Typ , es könnte sich umString
einen numerischen Wert handeln (ich musste auch die Exponentialschreibweise usw. berücksichtigen), einNumber
Objekt, An diese Funktion konnte praktisch alles übergeben werden, ich konnte keine Typannahmen treffen und mich um den Typzwang kümmern (z. B. sollte+true == 1;
abertrue
nicht als betrachtet werden"numeric"
).Ich denke, es lohnt sich, diesen Satz von +30 Komponententests für zahlreiche Funktionsimplementierungen zu teilen und auch den zu teilen, der alle meine Tests besteht:
PS isNaN & isFinite verhalten sich aufgrund der erzwungenen Konvertierung in Zahlen verwirrend. In ES6 würde Number.isNaN & Number.isFinite diese Probleme beheben. Denken Sie daran, wenn Sie sie verwenden.
Update : So macht es jQuery jetzt (2.2-stabil) :
Update : Angular 4.3 :
quelle
2e308 > Number.MAX_VALUE
da2e308 == Infinity
. Wenn Sie eine Funktion wünschen, dietrue
auch positive und negative Unendlichkeitswerte zurückgibt , überprüfen Sie die Funktion Nr. 2 in der Testsuite . Prost.Arrrgh! Hören Sie nicht auf die Antworten mit regulären Ausdrücken. RegEx ist dafür eklig, und ich spreche nicht nur von Leistung. Es ist so einfach, subtile Fehler zu machen, die mit Ihrem regulären Ausdruck nicht zu erkennen sind.
Wenn Sie nicht verwenden können
isNaN()
, sollte dies viel besser funktionieren:So funktioniert das:
Der
(input - 0)
Ausdruck zwingt JavaScript, einen Typzwang für Ihren Eingabewert auszuführen. Es muss zuerst als Zahl für die Subtraktionsoperation interpretiert werden. Wenn diese Konvertierung in eine Zahl fehlschlägt, führt der Ausdruck zuNaN
. Dieses numerische Ergebnis wird dann mit dem ursprünglich übergebenen Wert verglichen. Da die linke Seite jetzt numerisch ist, wird erneut der Typ Zwang verwendet. Nachdem die Eingabe von beiden Seiten aus demselben ursprünglichen Wert auf denselben Typ gezwungen wurde, würden Sie denken, dass sie immer gleich sein sollten (immer wahr). Es gibt jedoch eine spezielle Regel, die besagt, dassNaN
niemals gleich ist.NaN
Daher führt ein Wert, der nicht in eine Zahl konvertiert werden kann (und nur Werte, die nicht in Zahlen konvertiert werden können), zu false.Die Überprüfung der Länge gilt für einen Sonderfall mit leeren Zeichenfolgen. Beachten Sie auch, dass dies bei Ihrem 0x89f-Test nicht der Fall ist. In vielen Umgebungen ist dies jedoch eine gute Möglichkeit, ein Zahlenliteral zu definieren. Wenn Sie dieses spezielle Szenario erfassen möchten, können Sie eine zusätzliche Prüfung hinzufügen. Noch besser, wenn dies Ihr Grund für die
isNaN()
Nichtverwendung ist, wickeln Sie einfach Ihre eigene Funktion umisNaN()
, die auch die zusätzliche Überprüfung durchführen kann.Zusammenfassend kann , wenn Sie wissen wollen , ob ein Wert in eine Zahl umgewandelt werden, tatsächlich versuchen , es in eine Zahl zu konvertieren.
Ich ging zurück und recherchierte, warum eine Whitespace-Zeichenfolge nicht die erwartete Ausgabe hatte, und ich glaube, ich verstehe sie jetzt: Eine leere Zeichenfolge wird
0
eher dazu gezwungen alsNaN
. Durch einfaches Trimmen der Zeichenfolge vor der Längenprüfung wird dieser Fall behandelt.Wenn Sie die Unit-Tests mit dem neuen Code ausführen, schlägt dies nur für die Infinity- und Booleschen Literale fehl. Das einzige Problem, das auftreten sollte, ist, wenn Sie Code generieren (wer würde wirklich ein Literal eingeben und prüfen, ob es numerisch ist? Sie sollten es wissen ), und das wäre ein seltsamer Code, den Sie generieren müssen.
Aber noch einmal, der einzige Grund , dies jemals zu verwenden ist , wenn Sie aus irgendeinem Grund isNaN vermeiden müssen ().
quelle
IsNumeric(' ')
,IsNumeric('\n\t')
usw. alle zurücktrue
Number
Literalen fehlschlagen.IsNumeric(5) == false;
Überprüfen Sie die von mir veröffentlichten Komponententests. Diese Funktion ist die Nummer16
in der Testsuite. stackoverflow.com/questions/18082/…Dieser Weg scheint gut zu funktionieren:
In einer Zeile:
Und um es zu testen:
Ich habe diesen regulären Ausdruck von http://www.codetoad.com/javascript/isnumeric.asp ausgeliehen . Erläuterung:
quelle
Yahoo! Die Benutzeroberfläche verwendet Folgendes:
quelle
new Number(1)
.Dies funktioniert auch für 0x23-Typennummern.
quelle
IsNumeric('')
,IsNumeric(' ')
,IsNumeric(true)
,IsNumeric(false)
,IsNumeric(null)
Zurückkehrentrue
stattfalse
.Die akzeptierte Antwort hat Ihren Test Nr. 7 nicht bestanden, und ich denke, das liegt daran, dass Sie Ihre Meinung geändert haben. Dies ist also eine Antwort auf die akzeptierte Antwort, mit der ich Probleme hatte.
Während einiger Projekte musste ich einige Daten validieren und so sicher wie möglich sein, dass es sich um einen numerischen Javascript-Wert handelt, der in mathematischen Operationen verwendet werden kann.
jQuery und einige andere Javascript-Bibliotheken enthalten bereits eine solche Funktion, die normalerweise aufgerufen wird
isNumeric
. Es gibt auch einen Beitrag zum Stapelüberlauf , der allgemein als Antwort akzeptiert wurde, dieselbe allgemeine Routine, die die oben genannten Bibliotheken verwenden.Erstens würde der obige Code true zurückgeben, wenn das Argument ein Array der Länge 1 wäre und dieses einzelne Element von einem Typ wäre, der von der obigen Logik als numerisch angesehen wird. Wenn es sich um ein Array handelt, ist es meiner Meinung nach nicht numerisch.
Um dieses Problem zu beheben, habe ich eine Überprüfung hinzugefügt, um Arrays von der Logik abzuziehen
Natürlich können Sie stattdessen auch
Array.isArray
jquery$.isArray
oder prototypeObject.isArray
verwendenObject.prototype.toString.call(n) !== '[object Array]'
Mein zweites Problem war, dass negative hexadezimale ganzzahlige Literalzeichenfolgen ("-0xA" -> -10) nicht als numerisch gezählt wurden. Positive hexadezimale ganzzahlige Literalzeichenfolgen ("0xA" -> 10) wurden jedoch als numerisch behandelt. Ich brauchte beide, um numerisch gültig zu sein.
Ich habe dann die Logik geändert, um dies zu berücksichtigen.
Wenn Sie sich Sorgen machen, dass der reguläre Ausdruck bei jedem Aufruf der Funktion erstellt wird, können Sie ihn innerhalb eines Abschlusses neu schreiben
Ich habe dann CMSs +30 Testfälle genommen und die Tests auf jsfiddle geklont und meine zusätzlichen Testfälle und meine oben beschriebene Lösung hinzugefügt.
Es ersetzt möglicherweise nicht die allgemein akzeptierte / verwendete Antwort, aber wenn dies mehr von dem ist, was Sie als Ergebnis Ihrer isNumeric-Funktion erwarten, dann wird dies hoffentlich eine Hilfe sein.
EDIT: Wie von Bergi hervorgehoben , gibt es andere mögliche Objekte, die als numerisch angesehen werden könnten, und es wäre besser, eine Whitelist als eine Blacklist zu erstellen. In diesem Sinne würde ich die Kriterien ergänzen.
Ich möchte, dass meine isNumeric-Funktion nur Zahlen oder Zeichenfolgen berücksichtigt
In diesem Sinne wäre es besser zu verwenden
Testen Sie die Lösungen
quelle
IsNumeric('99,999') => false
Ja, die integrierte
isNaN(object)
Analyse ist viel schneller als jede Regex-Analyse, da sie integriert und kompiliert ist, anstatt im laufenden Betrieb interpretiert zu werden.Obwohl die Ergebnisse etwas anders sind als das, wonach Sie suchen ( probieren Sie es aus ):
quelle
Verwenden Sie die Funktion
isNaN
. Ich glaube, wenn Sie es testen!isNaN(yourstringhere)
, funktioniert es in jeder dieser Situationen.quelle
Seit jQuery 1.7 können Sie Folgendes verwenden
jQuery.isNumeric()
:Beachten Sie nur, dass es sich im Gegensatz zu dem, was Sie gesagt haben,
0x89f
um eine gültige Zahl (hexa) handelt.quelle
Dies kann ohne RegExp as erfolgen
quelle
Mir ist klar, dass in der ursprünglichen Frage jQuery nicht erwähnt wurde, aber wenn Sie jQuery verwenden, können Sie Folgendes tun:
Einfach.
https://api.jquery.com/jQuery.isNumeric/ (ab jQuery 1.7)
quelle
hat bei mir nicht funktioniert. Als ich einen Alarm einlegte und testete,
input.length
warundefined
. Ich denke, es gibt keine Eigenschaft, um die Ganzzahllänge zu überprüfen. Also habe ich getanEs hat gut funktioniert.
quelle
Wenn ich mich nicht irre, sollte dies mit jedem gültigen JavaScript-Zahlenwert übereinstimmen, mit Ausnahme der Konstanten (
Infinity
,NaN
) und der Vorzeichenoperatoren+
/-
(da sie für mich nicht Teil der Zahl sind, sind sie separate Operatoren):Ich brauchte dies für einen Tokenizer, bei dem das Senden der Nummer an JavaScript zur Auswertung keine Option war ... Es ist definitiv nicht der kürzestmögliche reguläre Ausdruck, aber ich glaube, er erfasst alle feineren Feinheiten der Zahlensyntax von JavaScript.
Gültige Zahlen wären:
Ungültige Zahlen wären
quelle
Das einzige Problem, das ich mit der Antwort von @ CMS hatte , ist der Ausschluss von
NaN
und Infinity, die für viele Situationen nützliche Zahlen sind. Eine Möglichkeit, nachNaN
's zu suchen, besteht darin, nach numerischen Werten zu suchen, die nicht gleich sindNaN != NaN
. Es gibt also wirklich 3 Tests, mit denen Sie sich befassen möchten ...Meine isComparableNumber kommt einer anderen eleganten Antwort ziemlich nahe , verarbeitet jedoch Hex- und andere Zeichenfolgendarstellungen von Zahlen.
quelle
Für mich ist das der beste Weg:
quelle
Ich möchte Folgendes hinzufügen:
Positive Hex-Zahlen beginnen mit
0x
und negative Hex-Zahlen beginnen mit-0x
. Positive Okt-Zahlen beginnen mit0
und negative Okt-Zahlen beginnen mit-0
. Dieser berücksichtigt das meiste, was bereits erwähnt wurde, enthält jedoch Hex- und Oktalzahlen, negative wissenschaftliche Zahlen, Unendlichkeit und hat dezimale wissenschaftliche Zahlen entfernt (4e3.2
ist ungültig).quelle
Ich denke, die parseFloat-Funktion kann hier die ganze Arbeit erledigen. Die folgende Funktion besteht alle Tests auf dieser Seite, einschließlich
isNumeric(Infinity) == true
:quelle
IsNumeric([3]) == true;
IsNumeric([]) == false;
IsNumeric([3, 4]) == false;
Aber ich würde mir vorstellen, dass das Geschmackssache ist!Ein paar Tests zum Hinzufügen:
Ich habe mir das ausgedacht:
Die Lösung umfasst:
quelle
Ein ganzzahliger Wert kann überprüft werden durch:
Dieser Weg ist einfacher und schneller! Alle Tests werden überprüft!
quelle
Hier ist eine etwas verbesserte Version (wahrscheinlich der schnellste Weg da draußen), die ich anstelle der exakten jQuery-Variante verwende. Ich weiß wirklich nicht, warum sie diese nicht verwenden:
Der Nachteil von jQuerys Version ist, dass, wenn Sie eine Zeichenfolge mit führenden Zahlen und nachgestellten Buchstaben wie
"123abc"
dem übergebenparseFloat | parseInt
, der numerische Bruch extrahiert wird und 123 zurückgegeben wird, ABER der zweite WächterisFinite
wird ihn trotzdem nicht bestehen. Mit dem unären+
Operator wird es bei der allerersten Wache sterben, seit + NaN für solche Hybriden wirft :) Eine kleine Leistung, aber ich denke, ein solider semantischer Gewinn.quelle
Meine Lösung,
Es scheint in jeder Situation zu funktionieren, aber ich könnte mich irren.
quelle
?
für{0,1}
und\d
für verwenden würden[0-9]
. Außerdem können Sie die (nicht) erfassenden Gruppen verwenden und vergessen , wenn Sie+
sie dann einpacken .(?:){0,1}
*
Ich verwende eine einfachere Lösung:
quelle
Das sollte funktionieren. Einige der hier bereitgestellten Funktionen sind fehlerhaft und sollten auch schneller sein als jede andere Funktion hier.
Erklärt:
Erstellen Sie eine Kopie von sich selbst, konvertieren Sie die Zahl in float und vergleichen Sie sich dann mit der ursprünglichen Zahl, wenn es sich noch um eine Zahl handelt (ob Ganzzahl oder float), und stimmen Sie mit der ursprünglichen Zahl überein, dh, es handelt sich tatsächlich um eine Zahl.
Es funktioniert sowohl mit numerischen Zeichenfolgen als auch mit einfachen Zahlen. Funktioniert nicht mit Hexadezimalzahlen.
Achtung: Verwendung auf eigenes Risiko, keine Garantie.
quelle
Keine der Antworten gibt
false
für leere Zeichenfolgen zurück, ein Fix dafür ...quelle
Um zu überprüfen, ob eine Variable eine gültige Zahl enthält und nicht nur eine Zeichenfolge, die wie eine Zahl aussieht,
Number.isFinite(value)
.Dies ist Teil der Sprache seit ES2015
Beispiele:
quelle
Number.isFinite('0') -> false
Wenn n numerisch ist,
Number(n)
wird der numerische Wert zurückgegeben undtoString()
in eine Zeichenfolge umgewandelt. Wenn n nicht numerisch ist,Number(n)
wird es zurückgegeben,NaN
sodass es nicht mit dem Original übereinstimmtn
quelle
Mir ist klar, dass dies schon oft beantwortet wurde, aber das Folgende ist ein anständiger Kandidat, der in einigen Szenarien nützlich sein kann.
Es sollte beachtet werden, dass davon ausgegangen wird, dass '.42' KEINE Zahl ist und '4.' ist KEINE Zahl, daher sollte dies berücksichtigt werden.
Der besteht
isDecimal
den folgenden Test:Die Idee hier ist, dass jede Zahl oder Ganzzahl eine "kanonische" Zeichenfolgendarstellung hat und jede nicht-kanonische Darstellung abgelehnt werden sollte. Also setzen wir auf eine Zahl und zurück und prüfen, ob das Ergebnis die ursprüngliche Zeichenfolge ist.
Ob diese Funktionen für Sie nützlich sind, hängt vom Anwendungsfall ab. Ein Merkmal ist, dass unterschiedliche Zeichenfolgen unterschiedliche Zahlen darstellen (wenn beide den
isNumber()
Test bestehen).Dies ist zB für Zahlen als Objekteigenschaftsnamen relevant.
quelle
knockoutJs Integrierte Bibliotheksvalidierungsfunktionen
Durch Erweitern wird das Feld validiert
1) Nummer
self.number = ko.observable(numberValue)
.extend ({number: true}) ;Testfall
2) Ziffer
self.number = ko.observable(numberValue)
.extend ({digit: true}) ;Testfall
3) min und max
self.number = ko.observable(numberValue)
.extend ({min: 5}). verlängern ({max: 10}) ;Dieses Feld akzeptiert nur Werte zwischen 5 und 10
Testfall
quelle
Wenn Sie einen speziellen Satz von Dezimalstellen validieren müssen, können Sie dieses einfache Javascript verwenden:
http://codesheet.org/codesheet/x1kI7hAD
Das Javascript:
quelle
isNumeric=(el)=>{return Boolean(parseFloat(el)) && isFinite(el)}
Nichts sehr anderes, aber wir können den Booleschen Konstruktor verwenden
quelle