如何检查字符串是否为有效数字?

我希望在与旧的VB6IsNumeric()函数相同的概念空间中有一些东西?

1357957 次浏览

试试isAN函数

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

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

此函数与数字特定的Number.isNaN()方法不同。

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

Number.isNAN()不会将值转换为Number,并且对于任何不属于Number…类型的值都不会返回true。

parseInt(),但请注意,这个函数有点不同,例如它为parseInt(“100px”)返回100。

你可以用RegExp的方式:

var num = "987238";
if(num.match(/^-?\d+$/)){//valid integer (positive or negative)}else if(num.match(/^\d+\.\d+$/)){//valid float}else{//not valid number}

2020年10月2日:请注意,许多基本方法都充满了微妙的错误(例如空格、隐式部分解析、基数、数组的强制转换等),这里的许多答案都没有考虑到这些错误。以下实现可能对你有用,但请注意,它不适合小数点“.”以外的数字分隔符:

function isNumeric(str) {if (typeof str != "string") return false // we only process strings!return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...!isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail}

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

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

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

示例

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

当然,如果需要,你可以否定它。例如,要实现你给出的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')     // 12parseInt('aaa')    // NaNparseInt('12px')   // 12parseInt('foo2')   // NaN      These last three mayparseInt('12a5')   // 12       be different from whatparseInt('0x10')   // 16       you expected to see.

浮标

请记住,与+num不同,parseInt(顾名思义)将通过切断小数点后的所有内容将浮点数转换为整数(如果您想使用parseInt()因为此行为,你最好用另一种方法):

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

空字符串

空字符串可能有点反直觉。+num将空字符串或带空格的字符串转换为零,isNaN()假设相同:

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

但是parseInt()不同意:

parseInt('')       // NaNparseInt('   ')    // NaN

我用我做的这个…

到目前为止,它一直在工作:

function checkNumber(value) {return value % 1 == 0;}

如果你发现任何问题,请告诉我。

引用:

isNaN(num)//如果变量不包含有效数字则返回true

如果您需要检查前导/尾随空格,则不完全正确-例如,当需要一定数量的数字时,您需要获取“1111”而不是“111”或“111”以获取PIN输入。

最好使用:

var num = /^\d+$/.test(num)

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

科学记数法。

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

大浮点数可能表现得很奇怪

观察(使用Node.js):

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

另一方面:

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

因此,如果期望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);}

然而,即使是这个也远未完成。这里没有处理前导零,但它们确实会破坏长度测试。

PFB工作解决方案:

 function(check){check = check + "";var isNumber =   check.trim().length>0? !isNaN(check):false;return isNumber;}

如果您只是想检查字符串是否是整数(没有小数位),regex是一个很好的方法。其他方法如isNaN对于如此简单的东西来说太复杂了。

function isNumeric(value) {return /^-?\d+$/.test(value);}
console.log(isNumeric('abcd'));         // falseconsole.log(isNumeric('123a'));         // falseconsole.log(isNumeric('1'));            // trueconsole.log(isNumeric('1234567890'));   // trueconsole.log(isNumeric('-23'));          // trueconsole.log(isNumeric(1234));           // trueconsole.log(isNumeric(1234n));          // trueconsole.log(isNumeric('123.4'));        // falseconsole.log(isNumeric(''));             // falseconsole.log(isNumeric(undefined));      // falseconsole.log(isNumeric(null));           // false

要只允许积极整数,请使用:

function isNumeric(value) {return /^\d+$/.test(value);}
console.log(isNumeric('123'));          // trueconsole.log(isNumeric('-23'));          // false

在我的应用程序中,我们只允许a-z A-Z和0-9个字符。我发现上面使用“字符串%1===0”的答案有效,除非字符串以0xnn(如0x10)开头,然后在我们不想要它的时候它会将其返回为数字。在我的数字检查中,以下简单的陷阱似乎在我们的特定情况下起到了作用。

function isStringNumeric(str_input){//concat a temporary 1 during the modulus to keep a beginning hex switch combination from messing us up//very simple and as long as special characters (non a-z A-Z 0-9) are trapped it is finereturn '1'.concat(str_input) % 1 === 0;}

警告:这可能利用了JavaScript和ActionScript[Number("1"+the_string)%1===0)]中的长期bug,我不能说,但这正是我们所需要的。

我的解决方案:

// returns true for positive ints;// no scientific notation, hexadecimals or floating point dots
var isPositiveInt = function(str) {var result = true, chr;for (var i = 0, n = str.length; i < n; i++) {chr = str.charAt(i);if ((chr < "0" || chr > "9") && chr != ",") { //not digit or thousands separatorresult = false;break;};if (i == 0 && (chr == "0" || chr == ",")) {  //should not start with 0 or ,result = false;break;};};return result;};

您可以在循环中添加其他条件,以满足您的特定需求。

我是这样做的:

function isString(value){return value.length !== undefined;}function isNumber(value){return value.NaN !== undefined;}

当然,如果您传递其他定义了“长度”的对象,isString()将在此处被绊倒。

您可以在将参数传递给其构造函数时使用数量的结果。

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

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

    Number('34.00') // 34Number('-34') // -34Number('123e5') // 12300000Number('123e-5') // 0.00123Number('999999999999') // 999999999999Number('9999999999999999') // 10000000000000000 (integer accuracy up to 15 digit)Number('0xFF') // 255Number('Infinity') // Infinity
Number('34px') // NaNNumber('xyz') // NaNNumber('true') // NaNNumber('false') // NaN
// cavetsNumber('    ') // 0Number('\t\t') // 0Number('\n\t') // 0

我的尝试有点令人困惑,也许不是最好的解决方案

function isInt(a){return a === ""+~~a}

console.log(isInt('abcd'));         // falseconsole.log(isInt('123a'));         // falseconsole.log(isInt('1'));            // trueconsole.log(isInt('0'));            // trueconsole.log(isInt('-0'));           // falseconsole.log(isInt('01'));           // falseconsole.log(isInt('10'));           // trueconsole.log(isInt('-1234567890'));  // trueconsole.log(isInt(1234));           // falseconsole.log(isInt('123.4'));        // falseconsole.log(isInt(''));             // false
// other types then string returns falseconsole.log(isInt(5));              // falseconsole.log(isInt(undefined));      // falseconsole.log(isInt(null));           // falseconsole.log(isInt('0x1'));          // falseconsole.log(isInt(Infinity));       // false

如果你真的想确保一个字符串只包含一个数字,任何数字(整数或浮点数),并且正好是一个数字,你可以单独使用parseInt()/parseFloat()Number()!isNaN()。请注意,当Number()返回数字时,!isNaN()实际上返回true,当false返回NaN时,我将把它排除在其余的讨论之外。

parseFloat()的问题是,如果字符串包含任何数字,它将返回一个数字,即使字符串不包含只有完全数字:

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

Number()的问题是它会在传递的值根本不是数字的情况下返回一个数字!

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

滚动自己的正则表达式的问题是,除非您创建精确的正则表达式来匹配Javascript识别的浮点数,否则您将错过情况或识别不应该的情况。即使您可以滚动自己的正则表达式,为什么?有更简单的内置方法可以做到这一点。

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

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

如果有人能做到这一点,我花了一些时间破解这个试图修补moment.js(https://github.com/moment/moment)。

function isNumeric(val) {var _val = +val;return (val !== val + 1) //infinity check&& (_val === +val) //Cute coercion check&& (typeof val !== 'object') //Array/object check}

处理以下案件:

真的!:

isNumeric("1"))isNumeric(1e10))isNumeric(1E10))isNumeric(+"6e4"))isNumeric("1.2222"))isNumeric("-1.2222"))isNumeric("-1.222200000000000000"))isNumeric("1.222200000000000000"))isNumeric(1))isNumeric(0))isNumeric(-0))isNumeric(1010010293029))isNumeric(1.100393830000))isNumeric(Math.LN2))isNumeric(Math.PI))isNumeric(5e10))

假!:

isNumeric(NaN))isNumeric(Infinity))isNumeric(-Infinity))isNumeric())isNumeric(undefined))isNumeric('[1,2,3]'))isNumeric({a:1,b:2}))isNumeric(null))isNumeric([1]))isNumeric(new Date()))

讽刺的是,我最挣扎的是:

isNumeric(new Number(1)) => false

欢迎任何建议:)

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

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

注意!这将拒绝像.140.00008000.1这样的字符串。它非常挑剔-字符串必须匹配数字的“极小完美形式”才能通过此测试。

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

我已经测试过了,迈克尔的解决方案是最好的。在上面为他的答案投票(搜索此页面的“如果你真的想确保一个字符串”找到它)。本质上,他的答案是这样的:

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

它适用于我在这里记录的每个测试用例:https://jsfiddle.net/wggehvp9/5/

许多其他解决方案在这些边缘情况下都失败了:''、null、""、true和[]。理论上,您可以使用它们,并进行适当的错误处理,例如:

return !isNaN(num);

return (+num === +num);

特殊处理/\s/, null,"", true, false,[](还有其他的?)

为什么jQuery的实现不够好?

function isNumeric(a) {var b = a && a.toString();return !$.isArray(a) && b - parseFloat(b) + 1 >= 0;};

迈克尔建议这样做(尽管我在这里偷了“user1691651-John”的修改版本):

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

以下是一个性能很可能很差但结果可靠的解决方案。它是由jQuery 1.12.4实现和Michael的答案制成的装置,额外检查了前导/尾随空格(因为Michael的版本对于具有前导/尾随空格的数字返回true):

function isNumeric(a) {var str = a + "";var b = a && a.toString();return !$.isArray(a) && b - parseFloat(b) + 1 >= 0 &&!/^\s+|\s+$/g.test(str) &&!isNaN(str) && !isNaN(parseFloat(str));};

不过,后一个版本有两个新变量。可以通过以下操作绕过其中之一:

function isNumeric(a) {if ($.isArray(a)) return false;var b = a && a.toString();a = a + "";return b - parseFloat(b) + 1 >= 0 &&!/^\s+|\s+$/g.test(a) &&!isNaN(a) && !isNaN(parseFloat(a));};

我还没有对这些进行太多的测试,除了手动测试我将在当前困境中遇到的几个用例,这都是非常标准的东西。这是一个“站在巨人的肩膀上”的情况。

您可以使用类型,例如流式图书馆y,来获得静态的编译时检查。当然对用户输入不是很有用。

// @flow
function acceptsNumber(value: number) {// ...}
acceptsNumber(42);       // Works!acceptsNumber(3.14);     // Works!acceptsNumber(NaN);      // Works!acceptsNumber(Infinity); // Works!acceptsNumber("foo");    // Error!

这是一个优雅的单行,用于检查sNum是否是有效的数值。该代码也已针对各种输入进行了测试。

// returns True if sNum is a numeric value!!sNum && !isNaN(+sNum.replace(/\s|\$/g, ''));

帽子提示@gman以捕获错误。

我喜欢这种简单性。

Number.isNaN(Number(value))

上面是常规的Javascript,但我将它与typecript打字机结合使用以进行智能类型检查。这对于typecript编译器非常有用,可以为您提供正确的智能感知,并且没有类型错误。

打字稿打字机

警告:见下面杰里米的评论。这对某些值有一些问题,我现在没有时间修复它,但是使用打字稿打字机的想法很有用,所以我不会删除这部分。

isNotNumber(value: string | number): value is string {return Number.isNaN(Number(this.smartImageWidth));}isNumber(value: string | number): value is number {return Number.isNaN(Number(this.smartImageWidth)) === false;}

假设您有一个属性width,它是number | string。您可能希望根据它是否是字符串来执行逻辑。

var width: number|string;width = "100vw";
if (isNotNumber(width)){// the compiler knows that width here must be a stringif (width.endsWith('vw')){// we have a 'width' such as 100vw}}else{// the compiler is smart and knows width here must be numbervar doubleWidth = width * 2;}

typeGuard足够聪明,可以将if语句中的width类型限制为仅string。这允许编译器允许width.endsWith(...),如果类型为string | number,它将不允许。

你可以随意称呼打字机isNotNumberisNumberisStringisNotString,但我认为isString有点模棱两可,更难阅读。

我最近写了一篇关于如何确保变量是有效数字的文章:https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md这篇文章解释了如何确保浮点数或整数,如果这很重要(+x vs~~x)。

这篇文章假设变量是stringnumber开始,trim是可用的/多填充的。扩展它来处理其他类型也不难。这是它的核心:

// Check for a valid floatif (x == null|| ("" + x).trim() === ""|| isNaN(+x)) {return false;  // not a float}
// Check for a valid integerif (x == null|| ("" + x).trim() === ""|| ~~x !== +x) {return false;  // not an integer}

这个问题的公认答案有很多缺陷(正如其他几个用户强调的那样)。这是在JavaScript中处理它的最简单且经过验证的方法之一:

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

下面是一些很好的测试用例:

console.log(isNumeric(12345678912345678912)); // trueconsole.log(isNumeric('2 '));                 // trueconsole.log(isNumeric('-32.2 '));             // trueconsole.log(isNumeric(-32.2));                // trueconsole.log(isNumeric(undefined));            // false
// the accepted answer fails at these tests:console.log(isNumeric(''));                   // falseconsole.log(isNumeric(null));                 // falseconsole.log(isNumeric([]));                   // false

省去试图找到“内置”解决方案的头痛。

没有一个好的答案,这篇文章中投票支持的答案是错误的。

npm install is-number

在JavaScript中,可靠地检查一个值是否是数字并不总是那么简单。开发人员通常使用 +, -, 或Number()将字符串值转换为数字(例如,当从用户输入、正则表达式匹配、解析器等返回值时)。但是有许多非直观的边缘情况会产生意想不到的结果:

console.log(+[]); //=> 0console.log(+''); //=> 0console.log(+'   '); //=> 0console.log(typeof NaN); //=> 'number'
function isNumberCandidate(s) {const str = (''+ s).trim();if (str.length === 0) return false;return !isNaN(+str);}
console.log(isNumberCandidate('1'));       // trueconsole.log(isNumberCandidate('a'));       // falseconsole.log(isNumberCandidate('000'));     // trueconsole.log(isNumberCandidate('1a'));      // falseconsole.log(isNumberCandidate('1e'));      // falseconsole.log(isNumberCandidate('1e-1'));    // trueconsole.log(isNumberCandidate('123.3'));   // trueconsole.log(isNumberCandidate(''));        // falseconsole.log(isNumberCandidate(' '));       // falseconsole.log(isNumberCandidate(1));         // trueconsole.log(isNumberCandidate(0));         // trueconsole.log(isNumberCandidate(NaN));       // falseconsole.log(isNumberCandidate(undefined)); // falseconsole.log(isNumberCandidate(null));      // falseconsole.log(isNumberCandidate(-1));        // trueconsole.log(isNumberCandidate('-1'));      // trueconsole.log(isNumberCandidate('-1.2'));    // trueconsole.log(isNumberCandidate(0.0000001)); // trueconsole.log(isNumberCandidate('0.0000001')); // trueconsole.log(isNumberCandidate(Infinity));    // trueconsole.log(isNumberCandidate(-Infinity));    // true
console.log(isNumberCandidate('Infinity'));  // true
if (isNumberCandidate(s)) {// use +s as a number+s ...}

只需使用isNaN(),这将把字符串转换为数量,如果得到有效的数量,将返回false

isNaN("Alireza"); //return trueisNaN("123"); //return false

我正在使用以下内容:

const isNumber = s => !isNaN(+s)

当防止空字符串和null

// Base cases that are handled properlyNumber.isNaN(Number('1')); // => falseNumber.isNaN(Number('-1')); // => falseNumber.isNaN(Number('1.1')); // => falseNumber.isNaN(Number('-1.1')); // => falseNumber.isNaN(Number('asdf')); // => trueNumber.isNaN(Number(undefined)); // => true
// Special notation cases that are handled properlyNumber.isNaN(Number('1e1')); // => falseNumber.isNaN(Number('1e-1')); // => falseNumber.isNaN(Number('-1e1')); // => falseNumber.isNaN(Number('-1e-1')); // => falseNumber.isNaN(Number('0b1')); // => falseNumber.isNaN(Number('0o1')); // => falseNumber.isNaN(Number('0xa')); // => false
// Edge cases that will FAIL if not guarded againstNumber.isNaN(Number('')); // => falseNumber.isNaN(Number(' ')); // => falseNumber.isNaN(Number(null)); // => false
// Edge cases that are debatableNumber.isNaN(Number('-0b1')); // => trueNumber.isNaN(Number('-0o1')); // => trueNumber.isNaN(Number('-0xa')); // => trueNumber.isNaN(Number('Infinity')); // => falseNumber.isNaN(Number('INFINITY')); // => trueNumber.isNaN(Number('-Infinity')); // => falseNumber.isNaN(Number('-INFINITY')); // => true

当不防范空字符串和null

使用parseInt

// Base cases that are handled properlyNumber.isNaN(parseInt('1')); // => falseNumber.isNaN(parseInt('-1')); // => falseNumber.isNaN(parseInt('1.1')); // => falseNumber.isNaN(parseInt('-1.1')); // => falseNumber.isNaN(parseInt('asdf')); // => trueNumber.isNaN(parseInt(undefined)); // => trueNumber.isNaN(parseInt('')); // => trueNumber.isNaN(parseInt(' ')); // => trueNumber.isNaN(parseInt(null)); // => true
// Special notation cases that are handled properlyNumber.isNaN(parseInt('1e1')); // => falseNumber.isNaN(parseInt('1e-1')); // => falseNumber.isNaN(parseInt('-1e1')); // => falseNumber.isNaN(parseInt('-1e-1')); // => falseNumber.isNaN(parseInt('0b1')); // => falseNumber.isNaN(parseInt('0o1')); // => falseNumber.isNaN(parseInt('0xa')); // => false
// Edge cases that are debatableNumber.isNaN(parseInt('-0b1')); // => falseNumber.isNaN(parseInt('-0o1')); // => falseNumber.isNaN(parseInt('-0xa')); // => falseNumber.isNaN(parseInt('Infinity')); // => trueNumber.isNaN(parseInt('INFINITY')); // => trueNumber.isNaN(parseInt('-Infinity')); // => trueNumber.isNaN(parseInt('-INFINITY')); // => true

使用parseFloat

// Base cases that are handled properlyNumber.isNaN(parseFloat('1')); // => falseNumber.isNaN(parseFloat('-1')); // => falseNumber.isNaN(parseFloat('1.1')); // => falseNumber.isNaN(parseFloat('-1.1')); // => falseNumber.isNaN(parseFloat('asdf')); // => trueNumber.isNaN(parseFloat(undefined)); // => trueNumber.isNaN(parseFloat('')); // => trueNumber.isNaN(parseFloat(' ')); // => trueNumber.isNaN(parseFloat(null)); // => true
// Special notation cases that are handled properlyNumber.isNaN(parseFloat('1e1')); // => falseNumber.isNaN(parseFloat('1e-1')); // => falseNumber.isNaN(parseFloat('-1e1')); // => falseNumber.isNaN(parseFloat('-1e-1')); // => falseNumber.isNaN(parseFloat('0b1')); // => falseNumber.isNaN(parseFloat('0o1')); // => falseNumber.isNaN(parseFloat('0xa')); // => false
// Edge cases that are debatableNumber.isNaN(parseFloat('-0b1')); // => falseNumber.isNaN(parseFloat('-0o1')); // => falseNumber.isNaN(parseFloat('-0xa')); // => falseNumber.isNaN(parseFloat('Infinity')); // => falseNumber.isNaN(parseFloat('INFINITY')); // => trueNumber.isNaN(parseFloat('-Infinity')); // => falseNumber.isNaN(parseFloat('-INFINITY')); // => true

备注:

  • 在解决原始问题时,只考虑字符串、空和未初始化的值。如果数组和对象是被考虑的值,则存在其他边缘情况。
  • 二进制、八进制、十六进制和指数表示法中的字符不区分大小写(即:'0xFF'、'0XFF'、'0xfF'等将在上面显示的测试用例中产生相同的结果)。
  • Infinity(区分大小写)不同,在某些情况下,将NumberMath对象作为字符串格式的测试用例传递给上述任何方法的常量将被确定为不是数字。
  • 请参阅了解参数如何转换为Number以及为什么存在null和空字符串的边缘情况。

它对TypeScript无效,因为:

declare function isNaN(number: number): boolean;

对于TypeScript,您可以使用:

/^\d+$/.test(key)

这是isNumber实现的高性能(2.5*10^7迭代/s@3.8GHz Haswell)版本。它适用于我能找到的每个测试用例(包括符号):

var isNumber = (function () {var isIntegerTest = /^\d+$/;var isDigitArray = [!0, !0, !0, !0, !0, !0, !0, !0, !0, !0];function hasLeading0s (s) {return !(typeof s !== 'string' ||s.length < 2 ||s[0] !== '0' ||!isDigitArray[s[1]] ||isIntegerTest.test(s));}var isWhiteSpaceTest = /\s/;return function isNumber (s) {var t = typeof s;var n;if (t === 'number') {return (s <= 0) || (s > 0);} else if (t === 'string') {n = +s;return !((!(n <= 0) && !(n > 0)) || n === '0' || hasLeading0s(s) || !(n !== 0 || !(s === '' || isWhiteSpaceTest.test(s))));} else if (t === 'object') {return !(!(s instanceof Number) || ((n = +s), !(n <= 0) && !(n > 0)));}return false;};})();

2019年:包括ES3、ES6和TypeScript示例

也许这已经被重复了太多次,但是我今天也和这个人打架,想发布我的答案,因为我没有看到任何其他答案可以简单或彻底地做到这一点:

ES3

var isNumeric = function(num){return (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);}

ES6

const isNumeric = (num) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);

打字稿

const isNumeric = (num: any) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num as number);

这似乎很简单,涵盖了我在许多其他帖子上看到的所有基础,并自己想出了:

// Positive Casesconsole.log(0, isNumeric(0) === true);console.log(1, isNumeric(1) === true);console.log(1234567890, isNumeric(1234567890) === true);console.log('1234567890', isNumeric('1234567890') === true);console.log('0', isNumeric('0') === true);console.log('1', isNumeric('1') === true);console.log('1.1', isNumeric('1.1') === true);console.log('-1', isNumeric('-1') === true);console.log('-1.2354', isNumeric('-1.2354') === true);console.log('-1234567890', isNumeric('-1234567890') === true);console.log(-1, isNumeric(-1) === true);console.log(-32.1, isNumeric(-32.1) === true);console.log('0x1', isNumeric('0x1') === true);  // Valid number in hex// Negative Casesconsole.log(true, isNumeric(true) === false);console.log(false, isNumeric(false) === false);console.log('1..1', isNumeric('1..1') === false);console.log('1,1', isNumeric('1,1') === false);console.log('-32.1.12', isNumeric('-32.1.12') === false);console.log('[blank]', isNumeric('') === false);console.log('[spaces]', isNumeric('   ') === false);console.log('null', isNumeric(null) === false);console.log('undefined', isNumeric(undefined) === false);console.log([], isNumeric([]) === false);console.log('NaN', isNumeric(NaN) === false);

您还可以尝试自己的isNumeric函数,并在这些用例中过去,并扫描所有用例的“true”。

或者,查看每个返回的值:

对<code>isNumery()</code>的每个测试的结果

2019年:实用和严格的数字有效性检查

通常,“有效数字”是指不包括NaN和Infinity的Javascript数字,即“有限数字”。

要检查值的数值有效性(例如来自外部源),您可以以ESlint Airbnb风格定义:

/*** Returns true if 'candidate' is a finite number or a string referring (not just 'including') a finite number* To keep in mind:*   Number(true) = 1*   Number('') = 0*   Number("   10  ") = 10*   !isNaN(true) = true*   parseFloat('10 a') = 10** @param {?} candidate* @return {boolean}*/function isReferringFiniteNumber(candidate) {if (typeof (candidate) === 'number') return Number.isFinite(candidate);if (typeof (candidate) === 'string') {return (candidate.trim() !== '') && Number.isFinite(Number(candidate));}return false;}

并以这种方式使用它:

if (isReferringFiniteNumber(theirValue)) {myCheckedValue = Number(theirValue);} else {console.warn('The provided value doesn\'t refer to a finite number');}

这是基于之前的一些答案和评论。以下涵盖了所有边缘情况,也相当简洁:

const isNumRegEx = /^-?(\d*\.)?\d+$/;
function isNumeric(n, allowScientificNotation = false) {return allowScientificNotation ?!Number.isNaN(parseFloat(n)) && Number.isFinite(n) :isNumRegEx.test(n);}

这似乎抓住了看似无限数量的边缘情况:

function isNumber(x, noStr) {/*
- Returns true if x is either a finite number type or a string containing only a number- If empty string supplied, fall back to explicit false- Pass true for noStr to return false when typeof x is "string", off by default
isNumber(); // falseisNumber([]); // falseisNumber([1]); // falseisNumber([1,2]); // falseisNumber(''); // falseisNumber(null); // falseisNumber({}); // falseisNumber(true); // falseisNumber('true'); // falseisNumber('false'); // falseisNumber('123asdf'); // falseisNumber('123.asdf'); // falseisNumber(undefined); // falseisNumber(Number.POSITIVE_INFINITY); // falseisNumber(Number.NEGATIVE_INFINITY); // falseisNumber('Infinity'); // falseisNumber('-Infinity'); // falseisNumber(Number.NaN); // falseisNumber(new Date('December 17, 1995 03:24:00')); // falseisNumber(0); // trueisNumber('0'); // trueisNumber(123); // trueisNumber(123.456); // trueisNumber(-123.456); // trueisNumber(-.123456); // trueisNumber('123'); // trueisNumber('123.456'); // trueisNumber('.123'); // trueisNumber(.123); // trueisNumber(Number.MAX_SAFE_INTEGER); // trueisNumber(Number.MAX_VALUE); // trueisNumber(Number.MIN_VALUE); // trueisNumber(new Number(123)); // true*/
return ((typeof x === 'number' || x instanceof Number || (!noStr && x && typeof x === 'string' && !isNaN(x))) &&isFinite(x)) || false;};

我使用这个函数作为表单验证工具,我不希望用户能够编写指数函数,所以我想出了这个函数:

<script>
function isNumber(value, acceptScientificNotation) {
if(true !== acceptScientificNotation){return /^-{0,1}\d+(\.\d+)?$/.test(value);}
if (true === Array.isArray(value)) {return false;}return !isNaN(parseInt(value, 10));}

console.log(isNumber(""));              // falseconsole.log(isNumber(false));           // falseconsole.log(isNumber(true));            // falseconsole.log(isNumber("0"));             // trueconsole.log(isNumber("0.1"));           // trueconsole.log(isNumber("12"));            // trueconsole.log(isNumber("-12"));           // trueconsole.log(isNumber(-45));             // trueconsole.log(isNumber({jo: "pi"}));      // falseconsole.log(isNumber([]));              // falseconsole.log(isNumber([78, 79]));        // falseconsole.log(isNumber(NaN));             // falseconsole.log(isNumber(Infinity));        // falseconsole.log(isNumber(undefined));       // falseconsole.log(isNumber("0,1"));           // false


console.log(isNumber("1e-1"));          // falseconsole.log(isNumber("1e-1", true));    // true</script>

因此,它将取决于您希望它处理的测试用例。

function isNumeric(number) {return !isNaN(parseFloat(number)) && !isNaN(+number);}

我在寻找的是JavaScript中的常规类型的数字。0, 1 , -1, 1.1 , -1.1 , 1E1 , -1E1 , 1e1 , -1e1, 0.1e10, -0.1.e10 , 0xAF1 , 0o172, Math.PI, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY

它们也表示为字符串:
'0', '1', '-1', '1.1', '-1.1', '1E1', '-1E1', '1e1', '-1e1', '0.1e10', '-0.1.e10', '0xAF1', '0o172'

我确实想省略它们,而不是将它们标记为数字'', ' ', [], {}, null, undefined, NaN

截至今天,所有其他答案似乎都没有通过其中一个测试案例。

检查JS中的数字:

  1. 检查它是否为数字的最佳方法:

    isFinite(20)//True
  2. 从字符串中读取一个值。CSS*:

    parseInt('2.5rem')//2parseFloat('2.5rem')//2.5
  3. 对于整数:

    isInteger(23 / 0)//False
  4. 如果值是NaN:

    isNaN(20)//False

测试字符串或数字是否为数字

const isNumeric = stringOrNumber =>stringOrNumber == 0 || !!+stringOrNumber;

或者如果您想将字符串或数字转换为数字

const toNumber = stringOrNumber =>stringOrNumber == 0 || +stringOrNumber ? +stringOrNumber : NaN;

太长别读

这在很大程度上取决于想要解析为数字的内容。

内置函数之间的比较

由于没有一个现有的来源满足我的灵魂,我试图弄清楚这些功能实际上发生了什么。

对这个问题的三个直接答案是:

  1. !isNaN(input)(输出与+input === +input相同)
  2. !isNaN(parseFloat(input))
  3. isFinite(input)

但是它们中的任何一个在场景中是正确的吗?

我在几个案例中测试了这些函数,并生成了Markdown输出。这是它的样子:

惊喜!JS不会解析字符串中的数字分隔符。有关详细信息,请检查这个问题。(为什么解析为浮点数有效?好吧,它没有。😉)
但是要小心!它比最大安全整数值253(大约9×1015)要大得多。阅读了解详情。
虽然没有看起来那么疯狂。在JavaScript中,大于~10的值308被四舍五入为无穷大,这就是原因。在这里查看了解详细信息。
是的,isNaN()将无穷大视为一个数字,parseFloat()将无穷大解析为无穷大。
input!isNaN(input)
+input===+input
!isNaN(
parseFloat(
input))
isFinite(
input)
评论
123✔️✔️✔️-
'123'✔️✔️✔️-
12.3✔️✔️✔️-
'12.3'✔️✔️✔️-
'12.3'✔️✔️✔️按照预期修剪了空空格。
1_000_000✔️✔️✔️理解数字分隔符,也需要。
'1_000_000'✔️
'0b11111111'✔️✔️✔️二进制形式的理解,因为它应该。
'0o377'✔️✔️✔️八进制形式也可以理解。
'0xFF'✔️✔️✔️当然十六进制是可以理解的。有没有人不这么认为?😒
''✔️✔️空字符串应该是一个数字吗?
' '✔️✔️一个只有空格的字符串应该是一个数字吗?
'abc'每个人都同意,不是一个数字。
'12.34Ab! @#$'✔️啊!现在很容易理解parseFloat()的作用了。对我来说不太印象深刻,但在某些情况下可能会派上用场。
'10e100'✔️✔️✔️
'10e1000'✔️✔️
null✔️✔️这就有点尴尬了。在JS中,当需要进行转换时,null会变成0,我们得到的是一个有限的数字。
那么为什么parseFloat(null)应该在这里返回NaN呢?谁来给我解释一下这个设计理念。
未定义和预期的一样。
无限✔️✔️如前所述,isNaN()将无穷大视为一个数字,parseFloat()将无穷大解析为无穷大。

那么,哪一个是“正确的”呢?

现在应该很清楚了,很大程度上取决于我们需要什么。例如,我们可能希望将空输入视为0。在这种情况下,isFinite()将正常工作。

同样,当需要1010000000000被认为是有效数字时,也许我们会从isNaN()那里得到一点帮助(尽管问题仍然存在-为什么会这样,以及我们将如何处理)!

当然,我们可以手动排除任何场景。

就像在我的例子中一样,我完全需要isFinite()的输出,除了null情况、空字符串情况和仅限空格的字符串情况。我也不担心非常巨大数字。所以我的代码看起来像这样:

/*** My necessity was met by the following code.*/
if (input === null) {// Null input} else if (input.trim() === '') {// Empty or whitespace-only string} else if (isFinite(input)) {// Input is a number} else {// Not a number}

而且,这是我生成表的JavaScript:

/*** Note: JavaScript does not print numeric separator inside a number.* In that single case, the markdown output was manually corrected.* Also, the comments were manually added later, of course.*/
let inputs = [123, '123', 12.3, '12.3', '   12.3   ',1_000_000, '1_000_000','0b11111111', '0o377', '0xFF','', '    ','abc', '12.34Ab!@#$','10e100', '10e1000',null, undefined, Infinity];
let markdownOutput = `| \`input\` | \`!isNaN(input)\` or <br>\`+input === +input\` | \`!isNaN(parseFloat(input))\` | \`isFinite(input)\` | Comment || :---: | :---: | :---: | :---: | :--- |\n`;
for (let input of inputs) {let outputs = [];outputs.push(!isNaN(input));outputs.push(!isNaN(parseFloat(input)));outputs.push(isFinite(input));
if (typeof input === 'string') {// Output with quotationsconsole.log(`'${input}'`);markdownOutput += `| '${input}'`;} else {// Output without quotesconsole.log(input);markdownOutput += `| ${input}`;}
for (let output of outputs) {console.log('\t' + output);if (output === true) {markdownOutput += ` | <div style="color:limegreen">true</div>`;// markdownOutput += ` | ✔️`; // for stackoverflow} else {markdownOutput += ` | <div style="color:orangered">false</div>`;// markdownOutput += ` | ❌`; // for stackoverflow}}
markdownOutput += ` ||\n`;}
// Replace two or more whitespaces with $nbsp;markdownOutput = markdownOutput.replaceAll(`  `, `&nbsp;&nbsp;`);
// Print markdown to consoleconsole.log(markdownOutput);

如果您正在寻找一个正数(例如,房屋编号),只需使用:

if (mystring > 0) ...

这种方式对我有效。

function isNumeric(num){let value1 = num.toString();let value2 = parseFloat(num).toString();return (value1 === value2);}

console.log(isNumeric(123),     //trueisNumeric(-123),    //trueisNumeric('123'),   //trueisNumeric('-123'),  //trueisNumeric(12.2),    //trueisNumeric(-12.2),   //trueisNumeric('12.2'),  //trueisNumeric('-12.2'), //trueisNumeric('a123'),  //falseisNumeric('123a'),  //falseisNumeric(' 123'),  //falseisNumeric('123 '),  //falseisNumeric('a12.2'), //falseisNumeric('12.2a'), //falseisNumeric(' 12.2'), //falseisNumeric('12.2 '), //false)

有人也可以从基于regex的答案中受益。这里是:

一个班轮是整数:

const isInteger = num => /^-?[0-9]+$/.test(num+'');

一个班轮是数字的:接受整数和小数

const isNumeric = num => /^-?[0-9]+(?:\.[0-9]+)?$/.test(num+'');

我在Angular中使用了这个函数

 isNumeric(value: string): boolean {let valueToNumber = Number(value);var result = typeof valueToNumber == 'number' ;if(valueToNumber.toString() == 'NaN'){result = false;}return result;}

如果你喜欢一种棘手的方式,你喜欢让你的同事感到困惑,你可以使用:

const isNumeric = str => parseFloat(str) === parseFloat(str)

证明:

 const isNumeric = str => parseFloat(str) === parseFloat(str) 
console.log(isNumeric('10'))console.log(isNumeric('-10.2'))console.log(isNumeric('15abc'))console.log(isNumeric('0.0001'))console.log(isNumeric('abc'))console.log(isNumeric('abc123'))

以下内容如何?

const a = '1'
const isNumber = (a) => Number(a) === +a

我认为isFinite()最适合所有人。

let a = isFinite('abc') // false;let b = isFinite('123')//true;let c = isFinite('12a') // false;console.log(a,b,c)

这是检查变量是否为数值的一种可能方法:

(isNaN(foo) || ((foo !== 0) && (!foo)))

这意味着foo要么是假的,但与0不同,要么isNaN(foo)是真的。

执行这种检查的另一种方法是

!isNaN(parseFloat(foo))

typeof运算符返回一个字符串,指示操作数值的类型。

对于数字,它返回“数量”字符串。

function isNumber(num) {return typeof num === "number";}