(Built-in) way in JavaScript to check if a string is a valid number
我希望在同一个概念空间中有什么东西与旧的vb6
要检查变量(包括字符串)是否是数字,请检查它是否不是数字:
不管变量内容是字符串还是数字,这都有效。
1 | isNaN(num) // returns true if the variable does NOT contain a valid number |
实例
1 2 3 4 5 | isNaN(123) // false isNaN('123') // false isNaN('1e10000') // false (This translates to Infinity, which is a number) isNaN('foo') // true isNaN('10px') // true |
当然,如果你需要的话,你可以否定这一点。例如,要实现
1 2 3 | function isNumeric(num){ return !isNaN(num) } |
要将包含数字的字符串转换为数字:
只有当字符串只包含数字字符时才有效,否则返回
1 2 | +num // returns the numeric value of the string, or NaN // if the string isn't purely numeric characters |
实例
1 2 3 4 5 6 7 | +'12' // 12 +'12.' // 12 +'12..' // Nan +'.12' // 0.12 +'..12' // Nan +'foo' // NaN +'12px' // NaN |
将字符串松散地转换为数字
用于将"12px"转换为12,例如:
1 2 | parseInt(num) // extracts a numeric value from the // start of the string, or NaN. |
实例
1 2 3 4 5 | 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. |
漂浮物
记住,与
1 2 3 | +'12.345' // 12.345 parseInt(12.345) // 12 parseInt('12.345') // 12 |
空字符串
空字符串可能有点违反直觉。
1 2 | +'' // 0 isNaN('') // false |
但
1 | parseInt('') // NaN |
你可以走Regexp的路:
1 2 3 4 5 6 7 8 9 | 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 } |
如果你只是想检查一个字符串是否是一个整数(没有小数点),那么regex是一个很好的方法。其他方法,如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
要只允许正整数,请使用此选项:
1 2 3 4 5 6 | function isNumeric(value) { return /^\d+$/.test(value); } console.log(isNumeric('123')); // true console.log(isNumeric('-23')); // false |
如果你真的想确保一个字符串只包含一个数字,任何数字(整数或浮点),以及一个确切的数字,你就不能自己使用EDCOX1,2,EDCX1,3,EDCOX1,4,或者EDCOX1,5。请注意,当EDOCX1引用4返回时,EDCOX1的5实际上是返回EDCOX1×7;EDCX1 9返回时,EDOCX1 OR 10表示,因此,我将将其排除在讨论的其余部分。
EDCOX1的3个问题是,如果字符串包含任何数字,即使字符串不包含和仅包含一个数字,它也会返回一个数字:
1 2 3 | parseFloat("2016-12-31") // returns 2016 parseFloat("1-1") // return 1 parseFloat("1.2.3") // returns 1.2 |
1 2 3 4 5 | Number("") // returns 0 Number("") // returns 0 Number(" \u00A0 \t ") // returns 0 |
滚动您自己的regex的问题是,除非您创建精确的regex来匹配一个浮点数,因为javascript识别它,否则您将错过案例或识别不应该出现的案例。即使您可以滚动自己的regex,为什么?有更简单的内置方式。
然而,事实证明,
1 2 3 4 5 | 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函数:
The isNaN() function determines whether a value is an illegal number (Not-a-Number).
This function returns true if the value equates to NaN. Otherwise it returns false.
This function is different from the Number specific Number.isNaN() method.
The global isNaN() function, converts the tested value to a Number, then tests it.
Number.isNan() does not convert the values to a Number, and will not return true for any value that is not of the type Number...
旧问题,但在给出的答案中有几点遗漏。
科学记数法。
大浮动数可能表现怪异
观察(使用No.js):
1 2 3 4 5 6 7 8 9 10 11 12 13 | > var s = Array(16 + 1).join('9') undefined > s.length 16 > s '9999999999999999' > !isNaN(s) true > Number(s) 10000000000000000 > String(Number(s)) === s false > |
另一方面:
1 2 3 4 5 6 7 8 9 | > 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 > |
因此,如果期望EDCOX1为11,那么最好将字符串限制在15位(省略前导零)。
无穷
1 2 3 4 5 6 7 | > typeof Infinity 'number' > !isNaN('Infinity') true > isFinite('Infinity') false > |
考虑到所有这些,检查给定的字符串是否是满足以下所有条件的数字:
- 非科学符号
- 可预测转换为
Number 和String 。 - 有限的
这不是一件容易的事。下面是一个简单的版本:
1 2 3 4 5 6 7 | 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); } |
然而,即使是这一个也远远不够完整。前导零不在这里处理,但它们会进行螺旋长度测试。
这个问题的公认答案有相当多的缺陷(如其他几个用户所强调的)。这是用JavaScript处理它的最简单且经验证的方法之一:
1 2 3 | function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } |
下面是一些好的测试用例:
1 2 3 4 5 6 7 8 9 10 | 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 |
也许有一两个人遇到这个问题,他们需要比平时更严格的检查(就像我一样)。在这种情况下,这可能有用:
1 2 3 | if(str === String(Number(str))) { // it's a"perfectly formatted" number } |
当心!这将拒绝诸如
它使用
parseInt(),但请注意,在这个函数的意义上有点不同,例如它为parseInt返回100("100px")。
将参数传递给其构造函数时,可以使用数字的结果。
如果参数(字符串)无法转换为数字,则返回NaN,因此可以确定提供的字符串是否为有效数字。
注:当传递空字符串或
\t'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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(' \t') // 0 |
我已经测试过了,迈克尔的解决方案是最好的。投票给他上面的答案(在这个页面上搜索"如果你真的想确定一个字符串"来找到它)。实质上,他的答案是:
1 2 3 4 | function isNumeric(num){ num ="" + num; //coerce num to be a string return !isNaN(num) && !isNaN(parseFloat(num)); } |
它适用于我在这里记录的每个测试用例:网址:https://jsfiddle.net/wggehvp9/5/
对于这些边缘情况,许多其他解决方案都失败了:"",空,"",真,和[]。理论上,您可以使用它们,并进行适当的错误处理,例如:
1 | return !isNaN(num); |
或
1 | return (+num === +num); |
特别处理/ s/,null,",true,false,[](和其他?)
嗯,我用的是我做的这个……
到目前为止,它一直在工作:
1 2 3 4 5 6 | function checkNumber(value) { if ( value % 1 == 0 ) return true; else return false; } |
如果你发现它有什么问题,请告诉我。
报价:
isNaN(num) // returns true if the variable does NOT contain a valid number
如果您需要检查前导/尾随空格,则不是完全正确的-例如,当需要一定数量的数字时,您需要获得,例如"1111",而不是"111"或"111",可能是一个管脚输入。
更好使用:
1 | var num = /^\d+$/.test(num) |
为什么jquery的实现不够好?
1 2 3 4 | function isNumeric(a) { var b = a && a.toString(); return !$.isArray(a) && b - parseFloat(b) + 1 >= 0; }; |
迈克尔提出了类似的建议(尽管我在这里偷了"user1691651-john"的修改版本):
1 2 3 4 | function isNumeric(num){ num ="" + num; //coerce num to be a string return !isNaN(num) && !isNaN(parseFloat(num)); } |
下面是一个性能很可能很差但效果很好的解决方案。它是由jquery 1.12.4实现和michael的答案生成的一个装置,对前导/尾随空格进行额外检查(因为michael的版本对于前导/尾随空格的数字返回true):
1 2 3 4 5 6 7 | 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)); }; |
后一种版本有两个新的变量。通过这样做,人们可以绕过其中之一:
1 2 3 4 5 6 7 8 | 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)); }; |
我还没有用任何其他方法来测试这些,除了手动测试我将用我目前的困境来打击的几个用例,这些都是非常标准的东西。这是一个"站在巨人肩膀上"的局面。
如果有人能做到这一点,我花了一些时间来破解这个补丁moment.js(https://github.com/moment/moment)。我从中拿走了一些东西:
1 2 3 4 5 6 | function isNumeric(val) { var _val = +val; return (val !== val + 1) //infinity check && (_val === +val) //Cute coercion check && (typeof val !== 'object') //Array/object check } |
处理以下情况:
真的!:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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)) |
错了!:
1 2 3 4 5 6 7 8 9 10 | 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())) |
具有讽刺意味的是,我正在与之斗争的是:
1 | isNumeric(new Number(1)) => false |
欢迎提出任何建议。:]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | function isNumberCandidate(s) { const str = (''+ s).trim(); if (str.length === 0) return false; return !isNaN(+str); } console.log(isNumberCandidate('1')); // true console.log(isNumberCandidate('a')); // false console.log(isNumberCandidate('000')); // true console.log(isNumberCandidate('1a')); // false console.log(isNumberCandidate('1e')); // false console.log(isNumberCandidate('1e-1')); // true console.log(isNumberCandidate('123.3')); // true console.log(isNumberCandidate('')); // false console.log(isNumberCandidate(' ')); // false console.log(isNumberCandidate(1)); // true console.log(isNumberCandidate(0)); // true console.log(isNumberCandidate(NaN)); // false console.log(isNumberCandidate(undefined)); // false console.log(isNumberCandidate(null)); // false console.log(isNumberCandidate(-1)); // true console.log(isNumberCandidate('-1')); // true console.log(isNumberCandidate('-1.2')); // true console.log(isNumberCandidate(0.0000001)); // true console.log(isNumberCandidate('0.0000001')); // true console.log(isNumberCandidate(Infinity)); // true console.log(isNumberCandidate(-Infinity)); // true console.log(isNumberCandidate('Infinity')); // true if (isNumberCandidate(s)) { // use +s as a number +s ... } |
工作方案:
1 2 3 4 5 | function(check){ check = check +""; var isNumber = check.trim().length>0? !isNaN(check):false; return isNumber; } |
我喜欢这个的简单。
1 | Number.isNaN(Number(value)) |
上面是常规的javascript,但我将它与一个用于智能类型检查的typescript类型保护结合使用。这对于类型脚本编译器来说非常有用,可以为您提供正确的智能感知,并且没有类型错误。
打字字体保护1 2 3 4 5 6 | 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; } |
假设你有一个财产
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var width: number|string; width ="100vw"; if (isNotNumber(width)) { // the compiler knows that width here must be a string if (width.endsWith('vw')) { // we have a 'width' such as 100vw } } else { // the compiler is smart and knows width here must be number var doubleWidth = width * 2; } |
typeguard足够智能,可以将
你想叫什么都行,你叫什么都行,
为自己省去寻找"内置"解决方案的麻烦。
没有一个很好的答案,而且在这条线索中被大大否决的答案是错误的。
In JavaScript, it's not always as straightforward as it should be to reliably check if a value is a number. It's common for devs to use +, -, or Number() to cast a string value to a number (for example, when values are returned from user input, regex matches, parsers, etc). But there are many non-intuitive edge cases that yield unexpected results:
1 2 3 4 | console.log(+[]); //=> 0 console.log(+''); //=> 0 console.log(+' '); //=> 0 console.log(typeof NaN); //=> 'number' |
我的尝试有点混乱,不是最好的解决办法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function isInt(a){ return a ===""+~~a } console.log(isInt('abcd')); // false console.log(isInt('123a')); // false console.log(isInt('1')); // true console.log(isInt('0')); // true console.log(isInt('-0')); // false console.log(isInt('01')); // false console.log(isInt('10')); // true console.log(isInt('-1234567890')); // true console.log(isInt(1234)); // true console.log(isInt('123.4')); // false console.log(isInt('')); // false // other types then string returns false console.log(isInt(5)); // false console.log(isInt(undefined)); // false console.log(isInt(null)); // false console.log(isInt('0x1')); // false console.log(isInt(Infinity)); // false |
使用纯javascript:
1 2 | Number.isNaN(Number('1')); // false Number.isNaN(Number('asdf')); // true |
使用LADAS:
1 2 | _.isNaN(_.toNumber('1')); // false _.isNaN(_.toNumber('asdf')); // true |
可以使用类型,如流库,以获得静态、编译时间检查。当然对用户输入不是很有用。
1 2 3 4 5 6 7 8 9 10 11 | // @flow function acceptsNumber(value: number) { // ... } acceptsNumber(42); // Works! acceptsNumber(3.14); // Works! acceptsNumber(NaN); // Works! acceptsNumber(Infinity); // Works! acceptsNumber("foo"); // Error! |
我的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // 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 separator result = false; break; }; if (i == 0 && (chr =="0" || chr ==",")) { //should not start with 0 or , result = false; break; }; }; return result; }; |
您可以在循环中添加其他条件,以满足您的特定需求。
在我的应用程序中,我们只允许a-z a-z和0-9个字符。我发现上面使用"string%1==0"的答案是有效的,除非字符串以0xnn(类似于0x10)开头,然后当我们不想返回它时,它会以数字形式返回。下面的数字检查中的简单陷阱在我们的特定情况下似乎起到了作用。
1 2 3 4 | 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 fine return '1'.concat(str_input) % 1 === 0;} |
警告:这可能是在利用javascript和actionscript中的一个长期存在的bug[数字("1"+字符串)%1==0)],我不能这么说,但这正是我们需要的。
这里有一个一行程序来检查
1 | !isNaN(+s.replace(/\s|\$/g, '')); // returns True if numeric value |
我最近写了一篇关于如何确保变量是一个有效数字的文章:https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md如果这很重要,文章解释了如何确保浮点或整数(
本文假设变量是一个
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Check for a valid float if (x == null || ("" + x).trim() ==="" || isNaN(+x)) { return false; // not a float } // Check for a valid integer if (x == null || ("" + x).trim() ==="" || ~~x !== +x) { return false; // not an integer } |
只需使用
1 2 | isNaN("Alireza"); //return true isNaN("123"); //return false |
我正在使用以下内容:
1 | const isNumber = s => !isNaN(+s) |
我是这样做的:
1 2 3 4 5 6 7 8 | function isString(value) { return value.length !== undefined; } function isNumber(value) { return value.NaN !== undefined; } |
当然,如果传递其他定义了"length"的对象,isString()将在此处被触发。