在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
我找到了简单的解决方案,可能不是最好的,但效果很好:)
所以,我接下来要做的是,将字符串解析为Int,并检查新变量的长度大小(现在是Int类型)是否和原始字符串变量的长度相同。从逻辑上讲,如果大小相同,则意味着字符串被完全解析为int,并且只有当字符串仅由数字“构成”时,这才是可能的。
var val=1+$(e).val()+'';
var n=parseInt(val)+'';
if(val.length == n.length )alert('Is int');
您可以很容易地将该代码放在函数中,如果int,则使用return true代替alert。记住,如果您在字符串中使用点或逗号,您将检查它是否仍然为false,因为您正在解析为int。
注意:在e.val上添加1+,因此不会删除起始零。
啊!不要听正则表达式的答案。RegEx很讨厌这个,我说的不仅仅是性能。用正则表达式很容易发现细微的、不可能发现的错误。
如果您不能使用isNaN(),这应该会更好:
function IsNumeric(input)
{
return (input - 0) == input && (''+input).trim().length > 0;
}
以下是它的工作原理:
(input-0)表达式强制JavaScript对输入值执行类型强制;它必须首先被解释为减法运算的数字。如果转换为数字失败,表达式将生成NaN。然后将此数字结果与传入的原始值进行比较。由于左侧现在是数字,因此再次使用类型强制。既然来自双方的输入被强制为来自相同原始值的相同类型,那么您会认为它们应该总是相同的(总是正确的)。然而,有一条特殊规则规定NaN永远不等于NaN,因此不能转换为数字的值(只有不能转换为数值的值)将导致错误。
长度检查用于涉及空字符串的特殊情况。还要注意,这取决于0x89f测试,但这是因为在许多环境中,这是定义数字文字的好方法。如果您想捕捉特定场景,可以添加额外的检查。更好的是,如果这是您不使用isNaN()的原因,那么只需将您自己的函数包装在isNaN)周围,这也可以进行额外的检查。
总之,如果您想知道某个值是否可以转换为数字,请尝试将其转换为数字。
我回去研究了为什么空白字符串没有预期的输出,我想我现在明白了:空字符串被强制为0而不是NaN。只需在长度检查之前修剪字符串即可处理这种情况。
针对新代码运行单元测试,它只会在无穷大和布尔文本上失败,唯一可能出现问题的是,如果你正在生成代码(真的,谁会键入文本并检查它是否为数字?你应该知道),那将是一些奇怪的代码。
但是,再次强调,使用此选项的唯一原因是,如果出于某种原因,您必须避免使用isNaN()。
这种方式似乎很有效:
function IsNumeric(input){
var RE = /^-{0,1}\d*\.{0,1}\d+$/;
return (RE.test(input));
}
在一行中:
const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);
要测试它:
常量IsNumeric=(num)=>/^-{0,1}\d*\。{0,1}\d+$/.test(num);函数TestIsNumeric(){var结果=“”results+=(IsNumeric('-1')?“通过”:“失败”)+“:IsNumeric('-1')=>true\n”;结果+=(IsNumeric('-1.5')?“通过”:“失败”)+“:IsNumeric('-1.5')=>true\n”;结果+=(IsNumeric(“0”)?“通过”:“失败”)+“:IsNumeric('0')=>true\n”;结果+=(IsNumeric(“0.42”)?“通过”:“失败”)+“:IsNumeric('0.42')=>true\n”;results+=(IsNumeric('.42')?“通过”:“失败”)+“:IsNumeric('.42')=>true\n”;results+=(!IsNumeric('99999')?“通过”:“失败”)+“:IsNumeric(‘99999’)=>false \n”;results+=(!IsNumeric('0x89f')?“通过”:“失败”)+“:IsNumeric('0x89f')=>false \n”;results+=(!IsNumeric('#abcdef')?“通过”:“失败”)+“:IsNumeric('#abcdef')=>false \n”;results+=(!IsNumeric('1.2.3')?“通过”:“失败”)+“:IsNumeric('1.2.3')=>false \n”;results+=(!IsNumeric(“”)?“通过”:“失败”)+“:IsNumeric(“”)=>false \n”;results+=(!IsNumeric('barh')?“通过”:“失败”)+“:IsNumeric('barh')=>false \n”;返回结果;}console.log(TestIsNumeric());.作为控制台包装{最大高度:100%!重要;顶部:0;}
我从那里借来的正则表达式http://www.codetoad.com/javascript/isnumeric.asp.说明:
/^ match beginning of string
-{0,1} optional negative sign
\d* optional digits
\.{0,1} optional decimal point
\d+ at least one digit
$/ match end of string
knockoutJs内置库验证函数
通过扩展它,该字段得到验证
1) 编号
self.number=ko.obsobservable(numberValue).exextend({number:true});
测试用例
numberValue = '0.0' --> true
numberValue = '0' --> true
numberValue = '25' --> true
numberValue = '-1' --> true
numberValue = '-3.5' --> true
numberValue = '11.112' --> true
numberValue = '0x89f' --> false
numberValue = '' --> false
numberValue = 'sfsd' --> false
numberValue = 'dg##$' --> false
2) 数字
self.number=ko.obsobservable(numberValue).exextend({digit:true});
测试用例
numberValue = '0' --> true
numberValue = '25' --> true
numberValue = '0.0' --> false
numberValue = '-1' --> false
numberValue = '-3.5' --> false
numberValue = '11.112' --> false
numberValue = '0x89f' --> false
numberValue = '' --> false
numberValue = 'sfsd' --> false
numberValue = 'dg##$' --> false
3) 最小值和最大值
self.number=可观察(numberValue).扩展({min:5}).扩展;
此字段仅接受介于5和10之间的值
测试用例
numberValue = '5' --> true
numberValue = '6' --> true
numberValue = '6.5' --> true
numberValue = '9' --> true
numberValue = '11' --> false
numberValue = '0' --> false
numberValue = '' --> false
@Joel的答案很接近,但在以下情况下会失败:
// Whitespace strings:
IsNumeric(' ') == true;
IsNumeric('\t\t') == true;
IsNumeric('\n\r') == true;
// Number literals:
IsNumeric(-1) == false;
IsNumeric(0) == false;
IsNumeric(1.1) == false;
IsNumeric(8e5) == false;
前段时间,我必须实现一个IsNumeric函数,以确定一个变量是否包含一个数值,无论其类型如何,它可能是一个包含数值的字符串(我还必须考虑指数表示法等),一个Number对象,实际上任何东西都可以传递给该函数,我无法做出任何类型假设,注意类型强制(例如,+true==1;但true不应被视为“数字”)。
我认为值得分享这组针对众多功能实现所做的+30个单元测试,并分享通过我所有测试的测试:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
P.S.isNaN和isFinite由于强制转换为数字而具有令人困惑的行为。在ES6中,Number.isNaN和Number.isFinite可以解决这些问题。使用它们时请记住这一点。
更新:jQuery现在是如何做到的(2.2稳定):
isNumeric: function(obj) {
var realStringObj = obj && obj.toString();
return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;
}
更新:角度4.3:
export function isNumeric(value: any): boolean {
return !isNaN(value - parseFloat(value));
}