在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
30 回答
我意识到原始问题没有提到jQuery,但是如果你使用jQuery,你可以这样做:
简单 .
https://api.jquery.com/jQuery.isNumeric/(自jQuery 1.7起)
这应该工作 . 这里提供的一些功能是有缺陷的,也应该比这里的任何其他功能更快 .
解释:
创建自己的副本,然后将数字转换为float,然后将其自身与原始数字进行比较,如果它仍然是数字(无论是整数还是浮点数),并且与原始数字匹配,这意味着它确实是一个数字 .
它适用于数字字符串和普通数字 . 不适用于十六进制数字 .
警告:使用风险自负,不保证 .
knockoutJs Inbuild library validation functions
通过扩展它,字段得到验证
1)号码
self.number = ko.observable(numberValue)
.extend() ;测试用例
2)数字
self.number = ko.observable(numberValue)
.extend() ;测试用例
3)最小和最大
self.number = ko.observable(numberValue)
.extend({ min: 5}).extend({ max: 10}) ;此字段仅接受5到10之间的值
测试用例
Arrrgh!不要听正则表达式的答案 . RegEx对此非常苛刻,我不只是说性能 . 用你的正则表达式来制作微妙的,不可能发现错误是如此容易 .
如果你不能使用
isNaN()
,这应该会更好:以下是它的工作原理:
(input - 0)
表达式强制JavaScript对输入值执行类型强制;必须首先将其解释为减法运算的数字 . 如果转换为数字失败,则表达式将导致NaN
. 然后将此数值结果与您传入的原始值进行比较 . 由于左侧现在是数字,因此再次使用类型强制 . 既然来自双方的输入都是从相同的原始值强制转换为相同的类型,那么您会认为它们应该始终相同(始终为真) . 但是,有一个特殊规则,即NaN
永远不会等于NaN
,因此无法转换为数字的值(只有无法转换为数字的值)将导致false .检查长度是针对涉及空字符串的特殊情况 . 另请注意,它会降低到您的0x89f测试,但's because in many environments that'是一种定义数字文字的好方法 . 如果要捕获该特定方案,可以添加其他检查 . 更好的是,如果这是你不使用
isNaN()
的原因,那么只需将自己的函数包裹在isNaN()
周围,这也可以进行额外的检查 .总之, if you want to know if a value can be converted to a number, actually try to convert it to a number.
我回去做了一些研究,为什么空格字符串没有预期的输出,我想我现在得到它:一个空字符串被强制转换为
0
而不是NaN
. 只需在长度检查之前修剪字符串就可以处理这种情况 .运行单元测试新代码,它只在无穷大和布尔文字上失败,唯一应该是问题的时候是_123321的数字?你应该知道),这将是一些奇怪的代码生成 .
但是,再一次, the only reason ever to use this is if for some reason you have to avoid isNaN().
使用函数
isNaN
. 我相信如果你测试!isNaN(yourstringhere)
它适用于任何这些情况 .对于空字符串,没有任何答案返回
false
,修复了...如果n为数字
Number(n)
将返回数值,toString()
将其返回字符串 . 但如果n不是数字Number(n)
将返回NaN
所以它将不匹配原始n
它可以在没有RegExp的情况下完成
要检查变量是否包含有效数字而不仅仅是看起来像数字的字符串,可以使用
Number.isFinite(value)
.自ES2015以来,这是该语言的一部分
例子:
从jQuery 1.7开始,你可以使用jQuery.isNumeric():
请注意,与您所说的不同,
0x89f
是有效数字(hexa)我意识到这已被多次回答,但以下是一个不错的候选人,在某些情况下可能会有用 .
应该注意的是,假设'.42'不是数字,'4'不是数字,所以应该考虑到这一点 .
isDecimal
通过以下测试:这里的想法是每个数字或整数都有一个“规范”字符串表示,并且每个非规范表示都应该被拒绝 . 所以我们转换为数字并返回,并查看结果是否是原始字符串 .
这些功能是否对您有用取决于用例 . 一个特征是不同的字符串表示不同的数字(如果两者都通过
isNumber()
测试) .这是相关的,例如数字作为对象属性名称 .
@CMS' answer:使用nodejs在我的机器上的空白案例中,您的代码段失败了 . 所以我把它结合起来@joel's answer以下内容:
我将它与那些浮动的案例进行了单独测试:
和那些没有浮点数的情况(包括空白空间和对象/数组):
一切都按预期工作 . 也许这有帮助 .
完整源代码可以在here找到 .
整数值可以通过以下方式验证:
这种方式更容易,更快!检查所有测试!
对我不起作用 . 当我发出警报并进行测试时,
input.length
是undefined
. 我认为没有属性来检查整数长度 . 所以我做的是它工作正常 .
要添加的几个测试:
我想出了这个:
解决方案包括:
开头是可选的负号
单个零,或一个或多个不以0开头的数字,或者只要一个句点跟随就没有任何数字
一个句点,后跟一个或多个数字
以下似乎适用于许多情况:
这是 Build 在这个答案的基础上(也是这个答案):https://stackoverflow.com/a/1561597/1985601
如果我没有弄错的话,这应该匹配任何有效的JavaScript数值,不包括常量(
Infinity
,NaN
)和符号运算符+
/-
(因为就我而言它们实际上并不是数字的一部分,它们是单独的运算符):我需要这个用于标记器,其中将数字发送到JavaScript进行评估不是一个选项...它绝对不是最短的正则表达式,但我相信它捕获了JavaScript的数字语法的所有细微的微妙之处 .
Valid numbers would include:
Invalid numbers would be
这是一个小改进版本(可能是最快的方式),我使用而不是精确的jQuery变体,我真的不知道为什么他们不使用这个:
jQuery版本的缺点是,如果你传递一个带有前导数字和尾随字母的字符串,如
"123abc"
,parseFloat | parseInt
将提取数字分数并返回123,但是,第二个警卫isFinite
无论如何都会失败 . 随着一元的+
运算符,它将在第一个后卫死亡,因为抛出NaN为这样的混合动力:)一点性能但我认为一个可靠的语义增益 .@Joel's answer非常接近,但在以下情况下会失败:
前段时间我不得不实现
IsNumeric
函数,以查明变量是否包含数值 regardless of its type ,它可能是包含数值的String
(我还必须考虑指数表示法等),Number
对象,几乎任何东西都可以传递给那个函数,我不能做任何类型的假设,照顾类型强制(例如+true == 1;
但true
不应该被认为是"numeric"
) .我认为值得分享这一套+30 unit tests对众多功能实现,并分享通过我所有测试的那一个:
P.S. isNaN&isFinite由于强制转换为数字而导致混乱行为 . 在ES6中,Number.isNaN&Number.isFinite将解决这些问题 . 使用它们时请记住这一点 .
Update :Here's how jQuery does it now (2.2-stable):
Update :Angular 4.3:
Yahoo! UI使用此:
对我来说,这是最好的方法:
我对@ CMS的answer唯一的问题是
NaN
和Infinity的排除,这在许多情况下都是有用的数字 . 一种检查NaN
's is to check for numeric values that don' t等于自己的方法,NaN != NaN
!所以你真的想要处理3个测试......我的isComparableNumber非常接近另一个优雅的answer,但处理数字的十六进制和其他字符串表示 .
我正在使用更简单的解决方案:
您可以通过很多方式最小化此功能,还可以使用自定义正则表达式为负值或自定义图表实现它:
是的,内置的isNaN(object)将比任何正则表达式解析快得多,因为它是内置和编译的,而不是动态解释 .
虽然结果与您正在寻找的结果有些不同(try it):
这适用于0x23类型数字 .
这种方式似乎运作良好:
并测试它:
我从http://www.codetoad.com/javascript/isnumeric.asp借了那个正则表达式 . 说明:
我的解决方案
它似乎适用于所有情况,但我可能错了 .
我想补充以下内容:
正十六进制数以
0x
开头,负十六进制数以-0x
开头 . 正oct数以0
开头,负oct数以-0
开头 . 这个包含了已经提到的大部分内容,但包括十六进制和八进制数,负科学,无穷大并删除了十进制科学(4e3.2
无效) .接受的答案没有通过你的测试#7,我想这是因为你改变了主意 . 所以这是对已接受的答案的回应,我遇到了问题 .
在某些项目中,我需要验证一些数据并尽可能确定它是一个可以在数学运算中使用的javascript数值 .
jQuery和其他一些javascript库已经包含了这样一个函数,通常称为
isNumeric
. 还有一个被广泛接受作为答案的post on stackoverflow,与上述图书馆正在使用的相同的一般例程 .首先,如果参数是长度为1的数组,则上面的代码将返回true,并且该单个元素是上述逻辑认为是数字的类型 . 在我看来,如果它是一个数组,那么它不是数字 .
为了缓解这个问题,我添加了一个检查来从逻辑中对数组进行折扣
当然,您也可以使用
Array.isArray
,jquery$.isArray
或原型Object.isArray
而不是Object.prototype.toString.call(n) !== '[object Array]'
我的第二个问题是负十六进制整数文字字符串(“-0xA” - > -10)未计入数字 . 但是,正十六进制整数文字字符串(“0xA” - > 10)被视为数字 . 我需要两个都是有效的数字 .
然后我修改了逻辑以考虑到这一点 .
如果你每次调用函数时都担心正则表达式的创建,那么你可以在一个闭包中重写它,就像这样
然后我拿了CMSs +30 test cases并克隆了testing on jsfiddle添加了我的额外测试用例和我上面提到的解决方案 .
它可能无法取代广泛接受/使用过的答案,但如果这更像是您希望的isNumeric函数的结果,那么希望这会有所帮助 .
EDIT: 正如Bergi指出的那样,还有其他可能被认为是数字的对象,白名单比黑名单更好 . 考虑到这一点,我会添加标准 .
我希望我的isNumeric函数只考虑数字或字符串
考虑到这一点,最好使用它
Test the solutions