在JavaScript中验证十进制数字的最干净,最有效的方法是什么?
奖励积分:
- 明晰。 解决方案应该干净简单。
- 跨平台。
测试用例:
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
#1楼
如果我没有记错,这应该匹配任何有效的JavaScript数值,但不包括常数( Infinity
, NaN
)和符号运营商+
/ -
因为它们是就我而言数量没有实际的一部分,它们是独立的运营商):
我需要用它作为令牌生成器,在其中不能将数字发送到JavaScript进行评估...绝对不是最短的正则表达式,但我相信它可以捕获JavaScript数字语法的所有细微之处。
/^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d))
(?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i
有效数字包括:
- 0
- 00
- 01
- 10
- 0e1
- 0e01
- .0
- 0.
- .0e1
- 0.e1
- 0.e00
- 0xf
- 0Xf
无效的数字将是
- 00e1
- 01e1
- 00.0
- 00x0
- .
- .e0
#2楼
我正在使用更简单的解决方案:
function isNumber(num) {
return parseFloat(num).toString() == num
}
#3楼
isNumber: function(o) {
return typeof o === 'number' && isFinite(o);
}
#4楼
从jQuery 1.7开始,您可以使用jQuery.isNumeric()
:
$.isNumeric('-1'); // true
$.isNumeric('-1.5'); // true
$.isNumeric('0'); // true
$.isNumeric('0.42'); // true
$.isNumeric('.42'); // true
$.isNumeric('0x89f'); // true (valid hexa number)
$.isNumeric('99,999'); // false
$.isNumeric('#abcdef'); // false
$.isNumeric('1.2.3'); // false
$.isNumeric(''); // false
$.isNumeric('blah'); // false
请注意,与您所说的不同, 0x89f
是有效数字(六)
#5楼
接受的答案未通过您的#7测试,我想这是因为您改变了主意。 因此,这是对我遇到的问题的答复。
在某些项目中,我需要验证一些数据,并尽可能确定它是可以在数学运算中使用的javascript数值。
jQuery和其他一些JavaScript库已经包含了这样的函数,通常称为isNumeric
。 关于堆栈溢出的文章也已被广泛接受为答案,与上述库所使用的一般例程相同。
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
首先,如果参数是一个长度为1的数组,并且上面的逻辑将该单个元素的类型视为数字,则上面的代码将返回true。 我认为,如果它是一个数组,那么它不是数字。
为了缓解此问题,我从逻辑上对折扣数组添加了检查
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}
当然,您也可以使用Array.isArray
,jquery $.isArray
或原型Object.isArray
代替Object.prototype.toString.call(n) !== '[object Array]'
我的第二个问题是负十六进制整数文字字符串(“ -0xA”-> -10)未被计为数字。 但是,正十六进制整数文字字符串(“ 0xA”-> 10)被视为数字。 我都需要同时输入有效的数字。
然后,我修改了逻辑以考虑到这一点。
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
如果您担心每次调用该函数时都会创建正则表达式,则可以在闭包内重写它,如下所示
var isNumber = (function () {
var rx = /^-/;
return function (n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
};
}());
然后,我接受了CMS + 30个测试用例,并在jsfiddle上克隆了测试,并添加了额外的测试用例和上述解决方案。
它可能无法代替已被广泛接受/使用的答案,但是,如果这是您期望的isNumeric函数的结果,那么希望对您有所帮助。
编辑:正如Bergi所指出的那样 ,还有其他可能的对象可能被认为是数字对象,将其列入黑名单比将其列入黑名单会更好。 考虑到这一点,我将增加标准。
我希望我的isNumeric函数仅考虑数字或字符串
考虑到这一点,最好使用
function isNumber(n) {
return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
测试解决方案
var testHelper = function() { var testSuite = function() { test("Integer Literals", function() { ok(isNumber("-10"), "Negative integer string"); ok(isNumber("0"), "Zero string"); ok(isNumber("5"), "Positive integer string"); ok(isNumber(-16), "Negative integer number"); ok(isNumber(0), "Zero integer number"); ok(isNumber(32), "Positive integer number"); ok(isNumber("040"), "Octal integer literal string"); ok(isNumber(0144), "Octal integer literal"); ok(isNumber("-040"), "Negative Octal integer literal string"); ok(isNumber(-0144), "Negative Octal integer literal"); ok(isNumber("0xFF"), "Hexadecimal integer literal string"); ok(isNumber(0xFFF), "Hexadecimal integer literal"); ok(isNumber("-0xFF"), "Negative Hexadecimal integer literal string"); ok(isNumber(-0xFFF), "Negative Hexadecimal integer literal"); }); test("Foating-Point Literals", function() { ok(isNumber("-1.6"), "Negative floating point string"); ok(isNumber("4.536"), "Positive floating point string"); ok(isNumber(-2.6), "Negative floating point number"); ok(isNumber(3.1415), "Positive floating point number"); ok(isNumber(8e5)