Validate decimal numbers in Javascript

Asked

Viewed 3,364 times

8

What is the simplest and correct way to validate a Javascript decimal number?

For example, how to implement a function IsNumeric that has the following test cases:

IsNumeric('-1')     true
IsNumeric('-1.5')   true
IsNumeric('0')      true
IsNumeric('0.42')   true
IsNumeric('.42')    true
IsNumeric('99,999') false
IsNumeric('0x89f')  false
IsNumeric('#abcdef')false
IsNumeric('1.2.3')  false
IsNumeric('')       false
IsNumeric('blah')   false
  • 1

    Related question: "How to check if there are numbers inside an input with Javascript?" (I do not regard this as duplicate, as it is simply a matter of avoiding digits in a field, but the answers contain additional relevant information)

  • Now that I’ve seen it, my '99,999' case should be true whereas it may be the number 99999 using , as a thousand-seat delimiter

  • It’s hard to put an expression that works in all cases, but one way to adapt the expression to accept thousands separated by comma is to put it before the point: (\,\d\d\d)*. It’s not perfect, because an expression like that ^-?\d*(\,\d\d\d)*\.?\d+$ would accept so much ,123 how much 12345,678 and even 1,2345 (because the point is optional), that is, it has many false positives. It remains to be seen whether your concern is greater with false positives or false negatives, and adjust the regex accordingly. Or, of course, to make a function more complex and/or not based on regex...

1 answer

10


I believe it would be through the use of a regular expression. An expression that satisfies all your proposed tests would be:

^-?\d*\.?\d+$

Example in jsFiddle. Explaining:

  • ^ string start
  • -? with or without less at the front
  • \d* zero or more digits (so that .42 valide, it is important to accept zero digits before the point)
  • \.? point or no point
  • \d+ one or more digits
  • $ end of string

Other expressions could be used if one wished to accept a wider range of numbers - such as grouping thousands using the comma (American standard), allowing scientific notation using the e (common in programming languages), allow a + in front beyond only a minus, etc. And an "obvious" problem with the proposed expression is that it does not reject numbers with zeroes left.

In the end, it is a matter of precisely identifying what format a string is expected to have to be considered "numerical" and adjust the expression accordingly. It may get a little big, but in my opinion it’s even simpler than trying a parse manual (only if what you consider "number" does not fit into a regular language is that a more sophisticated method is needed).

  • 1

    Note: one could also use the parseFloat for try to interpret the number, and check if it did not return NaN, the problem is that if the prefix of the string for a number it interprets this prefix and ignores the rest... So I don’t see a way to compose a practical solution using this function.

  • i made a change to jsFiddle now ta showing the result: http://jsfiddle.net/bruxohpotter/54N2q/7/ it would be better to compare without Eval?

  • @Harrypotter The test with eval is just one example, the function IsNumeric in itself does not use eval. Your fiddle went wrong because expressao is a string and esperado is a Boolean, so comparing them always returns false.

  • @Harrypotter to run the tests, you will have to remove the quotes from the function calls - since you removed Eval. It will work.

  • @mgibsonbr This problem of parseFloat + string prefixed with number can be circumvented using it in conjunction with the isFinite, since he does the parse for Number and Number of this string type returns NaN

  • 1

    @Andréfigueiredo really lacked to remove the quotation marks, I changed: http://jsfiddle.net/bruxohpotter/mVj9K/, vlw

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.