验证JavaScript中的十进制数字-IsNumeric()

时间:2020-03-05 18:41:08  来源:igfitidea点击:

在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

解决方案

回答

这种方式似乎很好用:

function IsNumeric(input){
    var RE = /^-{0,1}\d*\.{0,1}\d+$/;
    return (RE.test(input));
}

并对其进行测试:

// alert(TestIsNumeric());

function TestIsNumeric(){
    var results = ''
    results += (IsNumeric('-1')?"Pass":"Fail") + ": IsNumeric('-1') => true\n";
    results += (IsNumeric('-1.5')?"Pass":"Fail") + ": IsNumeric('-1.5') => true\n";
    results += (IsNumeric('0')?"Pass":"Fail") + ": IsNumeric('0') => true\n";
    results += (IsNumeric('0.42')?"Pass":"Fail") + ": IsNumeric('0.42') => true\n";
    results += (IsNumeric('.42')?"Pass":"Fail") + ": IsNumeric('.42') => true\n";
    results += (!IsNumeric('99,999')?"Pass":"Fail") + ": IsNumeric('99,999') => false\n";
    results += (!IsNumeric('0x89f')?"Pass":"Fail") + ": IsNumeric('0x89f') => false\n";
    results += (!IsNumeric('#abcdef')?"Pass":"Fail") + ": IsNumeric('#abcdef') => false\n";
    results += (!IsNumeric('1.2.3')?"Pass":"Fail") + ": IsNumeric('1.2.3') => false\n";
    results += (!IsNumeric('')?"Pass":"Fail") + ": IsNumeric('') => false\n";
    results += (!IsNumeric('blah')?"Pass":"Fail") + ": IsNumeric('blah') => false\n";

    return results;
}

我从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

回答

要添加几个测试:

IsNumeric('01.05') => false
IsNumeric('1.') => false
IsNumeric('.') => false

我想出了这个:

function IsNumeric(input) {
    return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input);
}

该解决方案涵盖:

  • 开头的可选负号
  • 一个零或者一个或者多个不以0开头的数字,或者只要有句号就没有
  • 一个后接一个或者多个数字的句点

回答

我想添加以下内容:

1. IsNumeric('0x89f') => true
2. IsNumeric('075') => true

正十六进制数字以" 0x"开头,负十六进制数字以" -0x"开头。
八进制正数以" 0"开头,八进制负数以" -0"开头。
该代码考虑了已经提到的大部分内容,但包括十六进制和八进制数字,负科学数,无穷大并删除了十进制科学数(" 4e3.2"无效)。

function IsNumeric(input){
  var RE = /^-?(0|INF|(0[1-7][0-7]*)|(0x[0-9a-fA-F]+)|((0|[1-9][0-9]*|(?=[\.,]))([\.,][0-9]+)?([eE]-?\d+)?))$/;
  return (RE.test(input));
}

回答

使用函数" isNaN"。我相信,如果我们测试!isNaN(yourstringhere),则在任何情况下都可以正常工作。

回答

是的,内置的isNaN(object)将比任何正则表达式解析都要快得多,因为它是内置和编译的,而不是即时解释的。

尽管结果与我们要查找的内容有所不同(尝试):

// IS NUMERIC
document.write(!isNaN('-1') + "<br />");      // true
document.write(!isNaN('-1.5') + "<br />");    // true
document.write(!isNaN('0') + "<br />");       // true
document.write(!isNaN('0.42') + "<br />");    // true
document.write(!isNaN('.42') + "<br />");     // true
document.write(!isNaN('99,999') + "<br />");  // false
document.write(!isNaN('0x89f') + "<br />");   // true
document.write(!isNaN('#abcdef') + "<br />"); // false
document.write(!isNaN('1.2.3') + "<br />");   // false
document.write(!isNaN('') + "<br />");        // true
document.write(!isNaN('blah') + "<br />");    // false

回答

无需RegExp即可完成,因为

function IsNumeric(data){
    return parseFloat(data)==data;
}

回答

啊!不要听正则表达式的答案。正则表达式对此很讨厌,我不只是在谈论性能。使用正则表达式使微妙,不可能发现错误非常容易。

如果我们不能使用isNaN(),这应该会更好:

function IsNumeric(input)
{
    return (input - 0) == input && (''+input).trim().length > 0;
}

运作方式如下:

(input 0)表达式强制JavaScript对输入值进行强制转换。首先必须将其解释为减法运算的数字。如果该转换为数字失败,则表达式将产生NaN。然后,将此数字结果与我们传入的原始值进行比较。由于左侧现在是数字,因此将再次使用强制类型。现在,将来自双方的输入都从相同的原始值强制转换为相同的类型,我们将认为它们应该始终相同(始终为true)。但是,有一条特殊的规则说" NaN"从不等于" NaN",因此无法转换为数字的值(只有无法转换为数字的值)将导致错误。

长度检查是针对涉及空字符串的特殊情况。还要注意,它取决于0x89f测试,但这是因为在许多环境中,这是定义数字文字的一种好方法。如果要赶上特定情况,可以添加其他检查。更好的是,如果这是我们不使用isNaN()的原因,那么只需将我们自己的函数包装在isNaN()周围,这也可以执行其他检查。

总之,如果我们想知道一个值是否可以转换为数字,请实际尝试将其转换为数字。

我回过头来进行了一些研究,以研究空白字符串为何没有预期的输出的原因,我想我现在明白了:一个空字符串被强制为0而不是NaN。只需在长度检查之前修剪字符串即可解决这种情况。

针对新代码运行单元测试,它仅在无穷和布尔文字上失败,并且唯一应该出现问题的时间是我们是否正在生成代码(真的,谁会输入文字并检查它是否为数字?我们应该知道),这将生成一些奇怪的代码。

但是,再次使用此功能的唯一原因是,如果出于某种原因必须避免使用isNaN()。

回答

雅虎! UI使用此:

isNumber: function(o) {
    return typeof o === 'number' && isFinite(o);
}

回答

function IsNumeric(num) {
     return (num >=0 || num < 0);
}

这也适用于0x23类型编号。

回答

@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"函数,以查明变量是否包含数值,无论其类型如何,都可能是包含数值的" String"(我还必须考虑指数表示法,等等。),一个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));
}

回答

对我来说,这是最好的方法:

isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}

回答

这应该工作。这里提供的某些功能有缺陷,也应该比这里的任何其他功能都快。

function isNumeric(n)
        {
            var n2 = n;
            n = parseFloat(n);
            return (n!='NaN' && n2==n);
        }

解释:

创建自己的副本,然后将数字转换为浮点数,然后将其与原始数字进行比较(如果它仍然是数字(整数或者浮点数)),并且与原始数字匹配,这意味着它确实是一个数字。

它适用于数字字符串以及纯数字。不适用于十六进制数字。

警告:使用后果自负,不做任何保证。