JavaScript 中的(内置)方式来检查字符串是否为有效数字

我希望在与旧的 VB6 IsNumeric()函数相同的概念空间中有东西吗?

答案

要检查变量(包括字符串)是否是数字,请检查它是否不是数字:

无论变量内容是字符串还是数字,这都有效。

isNaN(num)         // returns true if the variable does NOT contain a valid number

例子

isNaN(123)         // false
isNaN('123')       // false
isNaN('1e10000')   // false (This translates to Infinity, which is a number)
isNaN('foo')       // true
isNaN('10px')      // true

当然,您可以根据需要对此进行否定。例如,要实现您提供的IsNumeric示例:

function isNumeric(num){
  return !isNaN(num)
}

要将包含数字的字符串转换为数字:

仅当字符串包含数字字符时才有效,否则返回NaN

+num               // returns the numeric value of the string, or NaN 
                   // if the string isn't purely numeric characters

例子

+'12'              // 12
+'12.'             // 12
+'12..'            // Nan
+'.12'             // 0.12
+'..12'            // Nan
+'foo'             // NaN
+'12px'            // NaN

将字符串宽松地转换为数字

有助于将 “12px” 转换为 12,例如:

parseInt(num)      // extracts a numeric value from the 
                   // start of the string, or NaN.

例子

parseInt('12')     // 12
parseInt('aaa')    // NaN
parseInt('12px')   // 12
parseInt('foo2')   // NaN      These last two may be different
parseInt('12a5')   // 12       from what you expected to see.

浮点数

请记住,与+num不同, parseInt (顾名思义)将通过截取小数点后的所有内容将浮点数转换为整数(如果由于这种行为想使用parseInt() ,则可能更好)使用另一种方法代替 ):

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

空字符串

空字符串可能有点违反直觉。 +num将空字符串转换为零,并且isNaN()假定相同:

+''                // 0
isNaN('')          // false

但是parseInt()不同意:

parseInt('')       // NaN

您可以使用 RegExp 方式:

var num = "987238";

if(num.match(/^-{0,1}\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}

如果您只是想检查字符串是否为整数(无小数点),则正则表达式是一种不错的选择。诸如isNaN类的其他方法对于如此简单的事物而言过于复杂。

function isNumeric(value) {
    return /^-{0,1}\d+$/.test(value);
}

console.log(isNumeric('abcd'));         // false
console.log(isNumeric('123a'));         // false
console.log(isNumeric('1'));            // true
console.log(isNumeric('1234567890'));   // true
console.log(isNumeric('-23'));          // true
console.log(isNumeric(1234));           // true
console.log(isNumeric('123.4'));        // false
console.log(isNumeric(''));             // false
console.log(isNumeric(undefined));      // false
console.log(isNumeric(null));           // false

要只允许整数使用此:

function isNumeric(value) {
    return /^\d+$/.test(value);
}

console.log(isNumeric('123'));          // true
console.log(isNumeric('-23'));          // false

如果您确实要确保字符串仅包含数字,任何数字(整数或浮点数)以及正好是数字, 则不能通过以下方式使用parseInt() / parseFloat()Number()!isNaN()他们自己。请注意,当Number()返回数字时, !isNaN()实际上返回true ,而当其返回NaN时实际上返回false ,因此我将在其余的讨论中将其排除。

这个问题parseFloat()是,它会返回一个数字,如果字符串中包含任何数量,即使字符串不只是准确一些包含:

parseFloat("2016-12-31")  // returns 2016
parseFloat("1-1") // return 1
parseFloat("1.2.3") // returns 1.2

Number()的问题在于,如果传递的值根本不是数字,它将返回一个数字!

Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0   \t\n\r") // returns 0

滚动自己的正则表达式的问题在于,除非您创建了与浮点数匹配的确切正则表达式,否则 Javascript 会识别该正则表达式,否则您会错过某些情况,或者会发现本不应该的情况。即使您可以使用自己的正则表达式,为什么呢?有更简单的内置方法。

但是,事实证明,对于parseFloat()在不应该返回数字的情况下, Number() (和isNaN() )都会做正确的事情,反之亦然。因此,要找出一个字符串是否确实是唯一且仅是一个数字,请调用这两个函数并查看它们是否返回 true:

function isNumber(str) {
  if (typeof str != "string") return false // we only process strings!
  // could also coerce to string: str = ""+str
  return !isNaN(str) && !isNaN(parseFloat(str))
}

尝试isNan 函数

isNaN()函数确定一个值是否为非法数字(非数字)。

如果该值等于 NaN,则此函数返回 true。否则,它返回 false。

此函数不同于 Number 特定Number.isNaN()方法。

全局 isNaN()函数,将测试的值转换为 Number,然后对其进行测试。

Number.isNan()不会将值转换为 Number,并且对于任何非 Number 类型的值也不会返回 true。

这个问题的公认答案有很多缺陷(其他几个用户都强调了这一点)。这是在 javascript 中解决该问题的最简单且经过验证的方法之一:

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

以下是一些好的测试用例:

console.log(isNumeric(12345678912345678912)); // true
console.log(isNumeric('2 '));                 // true
console.log(isNumeric('-32.2 '));             // true
console.log(isNumeric(-32.2));                // true
console.log(isNumeric(undefined));            // false

// the accepted answer fails at these tests:
console.log(isNumeric(''));                   // false
console.log(isNumeric(null));                 // false
console.log(isNumeric([]));                   // false

旧问题,但给出的答案中缺少几点。

科学计数法。

!isNaN('1e+30')true ,但是在大多数情况下,当人们要求输入数字时,他们不想匹配1e+30类的东西。

较大的浮点数可能会表现出怪异

观察(使用 Node.js):

> var s = Array(16 + 1).join('9')
undefined
> s.length
16
> s
'9999999999999999'
> !isNaN(s)
true
> Number(s)
10000000000000000
> String(Number(s)) === s
false
>

另一方面:

> var s = Array(16 + 1).join('1')
undefined
> String(Number(s)) === s
true
> var s = Array(15 + 1).join('9')
undefined
> String(Number(s)) === s
true
>

因此,如果期望String(Number(s)) === s ,那么最好将您的字符串最多限制为 15 位(省略前导零)。

无穷

> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>

鉴于所有这些,请检查给定的字符串是否是一个满足以下所有条件的数字:

  • 非科学记数法
  • 可预测的转换为Number并返回String
  • 有限

这不是一件容易的事。这是一个简单的版本:

function isNonScientificNumberString(o) {
    if (!o || typeof o !== 'string') {
      // Should not be given anything but strings.
      return false;
    }
    return o.length <= 15 && o.indexOf('e+') < 0 && o.indexOf('E+') < 0 && !isNaN(o) && isFinite(o);
  }

但是,即使这一步也远远不够。此处不处理前导零,但它们会拧长长度测试。

我已经测试过,迈克尔的解决方案是最好的。投票给他上面的答案(在该页面上搜索 “如果您确实要确保该字符串” 以找到它)。本质上,他的答案是这样的:

function isNumeric(num){
  num = "" + num; //coerce num to be a string
  return !isNaN(num) && !isNaN(parseFloat(num));
}

它适用于每个测试用例,我在这里记录了这些内容: https : //jsfiddle.net/wggehvp9/5/

对于这些边缘情况,许多其他解决方案均失败:'',null,“”,true 和 []。从理论上讲,您可以通过适当的错误处理来使用它们,例如:

return !isNaN(num);

要么

return (+num === +num);

对 / \ s /,null,“”,true,false,[](还有其他?)进行特殊处理

将参数传递给构造函数时,可以使用Number的结果。

如果参数(字符串)不能转换为数字,则返回 NaN,因此您可以确定所提供的字符串是否为有效数字。

注意:当传递空字符串或'\t\t''\n\t'作为数字时,将返回 0;传递 true 将返回 1,而 false 则返回 0。

Number('34.00') // 34
    Number('-34') // -34
    Number('123e5') // 12300000
    Number('123e-5') // 0.00123
    Number('999999999999') // 999999999999
    Number('9999999999999999') // 10000000000000000 (integer accuracy up to 15 digit)
    Number('0xFF') // 255
    Number('Infinity') // Infinity  

    Number('34px') // NaN
    Number('xyz') // NaN
    Number('true') // NaN
    Number('false') // NaN

    // cavets
    Number('    ') // 0
    Number('\t\t') // 0
    Number('\n\t') // 0

也许有一个或两个遇到这个问题的人需要比平时更严格的检查(就像我一样)。在这种情况下,这可能会很有用:

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}

谨防!这将拒绝像琴弦.140.00008000.1 。这非常挑剔 - 字符串必须与数字的 “ 最最小完美形式 ” 匹配,此测试才能通过。

它使用StringNumber构造函数将字符串转换为数字,然后再次返回,从而检查 JavaScript 引擎的 “完美最小形式”(使用初始Number构造函数将其转换为最小形式)是否与原始字符串匹配。