Validate decimal numbers in JavaScript - IsNumeric

2018-12-30 23:29发布

What's the cleanest, most effective way to validate decimal numbers in JavaScript?

Bonus points for:

  1. Clarity. Solution should be clean and simple.
  2. Cross-platform.

Test cases:

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

30条回答
忆尘夕之涩
2楼-- · 2018-12-30 23:56

Only problem I had with @CMS's answer is the exclusion of NaN and Infinity, which are useful numbers for many situations. One way to check for NaN's is to check for numeric values that don't equal themselves, NaN != NaN! So there are really 3 tests you'd like to deal with ...

function isNumber(n) {
  n = parseFloat(n);
  return !isNaN(n) || n != n;
}
function isFiniteNumber(n) {
  n = parseFloat(n);
  return !isNaN(n) && isFinite(n);
}    
function isComparableNumber(n) {
  n = parseFloat(n);
  return (n >=0 || n < 0);
}

isFiniteNumber('NaN')
false
isFiniteNumber('OxFF')
true
isNumber('NaN')
true
isNumber(1/0-1/0)
true
isComparableNumber('NaN')
false
isComparableNumber('Infinity')
true

My isComparableNumber is pretty close to another elegant answer, but handles hex and other string representations of numbers.

查看更多
梦寄多情
3楼-- · 2018-12-30 23:57

If I'm not mistaken, this should match any valid JavaScript number value, excluding constants (Infinity, NaN) and the sign operators +/- (because they are not actually part of the number as far as I concerned, they are separate operators):

I needed this for a tokenizer, where sending the number to JavaScript for evaluation wasn't an option... It's definitely not the shortest possible regular expression, but I believe it catches all the finer subtleties of JavaScript's number syntax.

/^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d)) 
(?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i

Valid numbers would include:

 - 0
 - 00
 - 01
 - 10
 - 0e1
 - 0e01
 - .0
 - 0.
 - .0e1
 - 0.e1
 - 0.e00
 - 0xf
 - 0Xf

Invalid numbers would be

 - 00e1
 - 01e1
 - 00.0
 - 00x0
 - .
 - .e0
查看更多
孤独总比滥情好
4楼-- · 2018-12-30 23:58

Yahoo! UI uses this:

isNumber: function(o) {
    return typeof o === 'number' && isFinite(o);
}
查看更多
流年柔荑漫光年
5楼-- · 2018-12-30 23:58
function IsNumeric(num) {
     return (num >=0 || num < 0);
}

This works for 0x23 type numbers as well.

查看更多
明月照影归
6楼-- · 2018-12-30 23:58

To me, this is the best way:

isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}
查看更多
余生请多指教
7楼-- · 2018-12-30 23:58

A couple of tests to add:

IsNumeric('01.05') => false
IsNumeric('1.') => false
IsNumeric('.') => false

I came up with this:

function IsNumeric(input) {
    return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input);
}

The solution covers:

  • An optional negative sign at the beginning
  • A single zero, or one or more digits not starting with 0, or nothing so long as a period follows
  • A period that is followed by 1 or more numbers
查看更多
登录 后发表回答