在Javascript中验证十进制数-IsNumeric()

2561

在JavaScript中,验证十进制数的最干净、最有效的方法是什么?

额外加分项:

  1. 清晰易懂。解决方案应简洁明了。
  2. 跨平台。

测试用例:

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

272
请注意,在法国,99,999是一个有效的数字,它与英式/美式格式中的99.999是相同的。因此,如果您从输入表单中读取字符串,则99,999可能是真实的。请注意,这是一条翻译,不包括任何额外的解释或内容。 - Re0sless
5
请查看这篇文章和精彩评论 - powtac
82
十进制逗号是整个欧洲和俄罗斯(英国除外)的标准。 - Calmarius
93
jQuery 1.7 引入了 jQuery.isNumeric 工具函数:http://api.jquery.com/jQuery.isNumeric/。 - Ates Goral
26
jQuery.isNumeric 无法通过 OP 的第七个测试用例 (IsNumeric('0x89f') => *false*)。然而,我不确定是否同意这个测试用例。 - Tim Lehner
显示剩余5条评论
53个回答

4

这是我使用的一种稍微改进了一点的方式(可能是最快的方式),替代 jQuery 的原版。我真的不知道他们为什么不使用这个:

function isNumeric(val) {
    return !isNaN(+val) && isFinite(val);
}

jQuery版本的缺点是,如果你传递一个包含前导数字和尾随字母的字符串,如"123abc"parseFloat | parseInt将提取出数值部分并返回123,但第二个保护条件isFinite仍然会失败。 使用一元运算符+时,它将在第一个保护条件上失败,因为+对于这种混合类型会抛出NaN :) 我认为这会带来一些性能上的损失,但语义上更加清晰。

2
注意,一元运算符“+”会在对象上调用valueOf()方法 - 请参见此jsfiddle。同样,这也无法处理前导空格,就像前面的答案一样。 - earcam

3

没有一个答案对空字符串返回false,需要修复这个问题...

function is_numeric(n)
{
 return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}

3

我的解决方案,

function isNumeric(input) {
    var number = /^\-{0,1}(?:[0-9]+){0,1}(?:\.[0-9]+){0,1}$/i;
    var regex = RegExp(number);
    return regex.test(input) && input.length>0;
}

它似乎在任何情况下都能工作,但我可能是错误的。


3
function inNumeric(n){
   return Number(n).toString() === n;
}

如果 n 是数字,则 Number(n) 将返回数字值,toString() 将其转换回字符串。但是如果 n 不是数字,则 Number(n) 将返回 NaN,因此它将无法匹配原始的 n

"1.20" 被转换为数字 1.2。因此,在这种情况下,这种方法不起作用。 - vinoth

3

这应该可以工作。这里提供的一些功能存在缺陷,但比这里的任何其他功能都要快。

        function isNumeric(n)
        {
            var n2 = n;
            n = parseFloat(n);
            return (n!='NaN' && n2==n);
        }

解释:

创建自身的副本,然后将数字转换为浮点数,然后将其与原始数字进行比较,如果它仍然是一个数字(无论是整数还是浮点数),并且匹配原始数字,那么就意味着它确实是一个数字。

它适用于数字字符串以及普通数字。不适用于十六进制数字。

警告:使用风险自负,不做任何保证。


3
我正在使用更简单的解决方案:
function isNumber(num) {
    return parseFloat(num).toString() == num
}

5
如果末尾有多余的0,这段代码将无法正常工作。例如:"10.0"。 - Janus Troelsen

3

这是一个超级简单的方法(在Chrome、Firefox和IE中测试过):

function isNumeric(x) {
  return parseFloat(x) == x;
}

问题中的测试用例:

console.log('trues');
console.log(isNumeric('-1'));
console.log(isNumeric('-1.5'));
console.log(isNumeric('0'));
console.log(isNumeric('0.42'));
console.log(isNumeric('.42'));

console.log('falses');
console.log(isNumeric('99,999'));
console.log(isNumeric('0x89f'));
console.log(isNumeric('#abcdef'));
console.log(isNumeric('1.2.3'));
console.log(isNumeric(''));
console.log(isNumeric('blah'));

更多测试案例:

console.log('trues');
console.log(isNumeric(0));
console.log(isNumeric(-1));
console.log(isNumeric(-500));
console.log(isNumeric(15000));
console.log(isNumeric(0.35));
console.log(isNumeric(-10.35));
console.log(isNumeric(2.534e25));
console.log(isNumeric('2.534e25'));
console.log(isNumeric('52334'));
console.log(isNumeric('-234'));
console.log(isNumeric(Infinity));
console.log(isNumeric(-Infinity));
console.log(isNumeric('Infinity'));
console.log(isNumeric('-Infinity'));

console.log('falses');
console.log(isNumeric(NaN));
console.log(isNumeric({}));
console.log(isNumeric([]));
console.log(isNumeric(''));
console.log(isNumeric('one'));
console.log(isNumeric(true));
console.log(isNumeric(false));
console.log(isNumeric());
console.log(isNumeric(undefined));
console.log(isNumeric(null));
console.log(isNumeric('-234aa'));

请注意,它将无穷大视为一个数字。


2
如果您需要验证一组特殊的小数y,您可以使用这个简单的Javascript代码:

http://codesheet.org/codesheet/x1kI7hAD

<input type="text" name="date" value="" pattern="[0-9]){1,2}(\.){1}([0-9]){2}" maxlength="6" placeholder="od npr.: 16.06" onchange="date(this);" />

这是Javascript代码:

function date(inputField) {        
  var isValid = /^([0-9]){1,2}(\.){1}([0-9]){2}$/.test(inputField.value);   
  if (isValid) {
    inputField.style.backgroundColor = '#bfa';
  } else {
    inputField.style.backgroundColor = '#fba';
  }
  return isValid;
}

2
无需使用额外的库。
const IsNumeric = (...numbers) => {
  return numbers.reduce((pre, cur) => pre && !!(cur === 0 || +cur), true);
};

测试

> IsNumeric(1)
true
> IsNumeric(1,2,3)
true
> IsNumeric(1,2,3,0)
true
> IsNumeric(1,2,3,0,'')
false
> IsNumeric(1,2,3,0,'2')
true
> IsNumeric(1,2,3,0,'200')
true
> IsNumeric(1,2,3,0,'-200')
true
> IsNumeric(1,2,3,0,'-200','.32')
true

2
我运行了下面的代码,所有测试用例都通过了...
它利用了parseFloatNumber处理输入的不同方式...
function IsNumeric(_in) {
    return (parseFloat(_in) === Number(_in) && Number(_in) !== NaN);
}

我没有尝试过这个,但是一个小建议:你可以将其简化为只返回 if 表达式,例如 return parseFloat... - Michael Haren
@Michael Haren,我真傻,刚才看到最高赞(关于30多个测试用例的那个)的这个链接http://dl.dropboxusercontent.com/u/35146/js/tests/isNumber.html,解释了很多问题... - Aaron Gong
1
这是错误的,你不能使用=====!=!==与NaN进行比较,它总是返回false。 - Alexis Wilke
关于NaN的棘手之处在于它与JavaScript中的每个值都不相等,包括它自己。因此,anythingAtAll === NaN是假的,而anythingAtAll !== NaN是真的。测试NaN的方法是将一个值与它本身进行比较:如果x是NaN,则x !== x为真,否则为假。 - jkdev
1
@jkdev 你也可以使用 isNaN(NaN),它会返回 true。这是 JavaScript 的内置函数。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isNaN - Jacob Gunther

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接