在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 (number is Infinity) 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', 10) // 12 parseInt('aaa', 10) // NaN parseInt('12px', 10) // 12 parseInt('foo2', 10) // NaN These last two may be different parseInt('12a5', 10) // 12 from what you expected to see.
花车
请记住,不同于+num
, parseInt
(顾名思义)将通过切断小数点后的所有内容(如果因为这种行为而使用parseInt()
)将float转换为整数,则可能更好用Math.floor()
代替):
parseInt(12.345, 10) // 12 parseInt('12.345', 10) // 12 +'12.345' // 12.345
空的字符串
空的字符串可能有点反直觉。 +num
将空字符串转换为零,并且isNaN()
假定相同:
+'' // 0 isNaN('') // false
但parseInt()
不同意:
parseInt('', 10) // NaN
你可以去RegExp的方式:
var num = "987238"; if(num.match(/^\d+$/)){ //valid integer }else if(num.match(/^\d+\.\d+$/)){ //valid float }else{ //not valid number }
尝试isNan函数 :
isNaN()函数确定一个值是否是一个非法数字(Not-a-Number)。
如果该值等于NaN,则该函数返回true。 否则,它返回false。
这个函数不同于Number 指定的Number.isNaN()方法。
全局isNaN()函数将测试值转换为数字,然后对其进行测试。
Number.isNan()不会将值转换为Number,并且不会返回任何非Number类型的值
如果你只是想检查一个字符串是否是一个整数(没有小数位),正则表达式是一个好方法。 其他方法如isNaN
太复杂了。
function isNumeric(value) { return /^\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(1234)); // true console.log(isNumeric('123.4')); // false console.log(isNumeric('')); // false console.log(isNumeric(undefined)); // false console.log(isNumeric(null)); // false
如果你真的想确保一个字符串只包含一个数字,任何数字(整数或浮点数),和一个数字,你不能使用parseInt()
/ parseFloat()
, Number()
或!isNaN()
他们自己。 请注意!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识别它,你将错过案例或识别你不应该的情况。 即使你可以推出自己的正则表达式,为什么呢? 有更简单的内置方法来做到这一点。
然而,事实证明Number()
(和isNaN()
)对于每个parseFloat()
返回一个数字的情况都是正确的,反之亦然。 因此,要找出一个字符串是否真的只是一个数字,请调用这两个函数,看看它们是否都返回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('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); }
但是,即使这个还远远没有完成。 前面的零不在这里处理,但他们拧螺丝的长度测试。
parseInt(),但是请注意,这个函数在parseInt(“100px”)返回100的意义上有些不同。
将参数传递给构造函数时,可以使用Number的结果。
如果参数(一个字符串)不能被转换成数字,它将返回NaN,所以你可以确定提供的字符串是否是有效的数字。
注意:当传递空字符串或'\t\t'
和'\n\t'
Number将返回0; 传递true将返回1,并返回false。
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 }
谨防! 这将拒绝像40.000
这样的字符串。 这是非常挑剔的 – 字符串必须匹配测试通过的数字的“ 最小完美形式 ”。
它使用String
和Number
构造函数将字符串转换为数字,然后再返回,从而检查JavaScript引擎的“完美最小形式”(使用初始Number
构造函数转换成的形式)是否匹配原始字符串。
我已经测试过,迈克尔的解决方案是最好的。 为上面的答案投票(搜索此页“如果你真的想确保一个字符串”来找到它)。 本质上,他的回答是这样的:
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,[](和其他?)进行特殊处理
那么,我正在使用这个我做的…
到目前为止,
function checkNumber(value) { if ( value % 1 == 0 ) return true; else return false; }
如果你发现任何问题,请告诉我。
引用:
isNaN(num)//如果变量不包含有效的数字,则返回true
如果您需要检查前导/尾随空格,例如当需要一定数量的数字,并且您需要获取(例如)“1111”而不是“111”或“111”输入。
更好地使用:
var num = /^\d+$/.test(num)
为什么jQuery的实现不够好?
function isNumeric(a) { var b = a && a.toString(); return !$.isArray(a) && b - parseFloat(b) + 1 >= 0; };
迈克尔建议像这样(虽然我偷了“user1691651 – 约翰”的改变版本在这里):
function isNumeric(num){ num = "" + num; //coerce num to be a string return !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)); };
我还没有测试任何这些,通过其他手段,而不是手动测试我将用我目前的困境,这是所有非常标准的东西打几个用例。 这是一个“站在巨人的肩膀上”的局面。
PFB的工作解决方案:
function(check){ check = check + ""; var isNumber = check.trim().length>0? !isNaN(check):false; return isNumber; }
我的尝试有点混乱,也许不是最好的解决方案
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
在我的应用程序中,我们只允许az AZ和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 az AZ 0-9) are trapped it is fine return '1'.concat(str_input) % 1 === 0;}
警告 :这可能是利用Javascript和Actionscript [数字(“1”+ the_string)%1 === 0)]长期存在的错误,我不能说这个,但这正是我们需要的。
我的解决方案
// 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; };
您可以在循环内添加其他条件,以适应您的特定需求。
如果有人得到这个很低的话,我花了一些时间试图修补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
欢迎任何建议。 :]
我这样做:
function isString(value) { return value.length !== undefined; } function isNumber(value) { return value.NaN !== undefined; }
当然,如果你传递了一些其他定义了“长度”的对象,isString()将会在这里被绊倒。