【问题标题】:Validate decimal numbers in JavaScript - IsNumeric()在 JavaScript 中验证十进制数字 - IsNumeric()
【发布时间】:2010-09-06 07:03:46
【问题描述】:

在 JavaScript 中验证十进制数字的最简洁、最有效的方法是什么?

奖励积分:

  1. 清晰。解决方案应该简洁明了。
  2. 跨平台。

测试用例:

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

【问题讨论】:

  • 请注意 99,999 在法国是一个有效数字,它与英国/美国格式的 99.999 相同,因此如果您从输入表单中读取字符串,那么 99,999 可能是正确的。
  • 小数逗号是整个欧洲和俄罗斯(英国除外)的标准
  • jQuery 1.7 引入了jQuery.isNumeric 实用函数:api.jquery.com/jQuery.isNumeric
  • jQuery.isNumeric 将失败 OP 的第七个测试用例 (IsNumeric('0x89f') => *false*)。不过,我不确定我是否同意这个测试用例。

标签: javascript validation numbers


【解决方案1】:

这种方式似乎效果不错:

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);

并对其进行测试:

const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);
    
    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;
    }

console.log(TestIsNumeric());
.as-console-wrapper { max-height: 100% !important; top: 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

【讨论】:

    【解决方案2】:

    添加几个测试:

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

    我想出了这个:

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

    解决方案包括:

    • 开头的可选负号
    • 单个零,或一个或多个不以 0 开头的数字,或者只要后面有句点就什么都没有
    • 后跟 1 个或多个数字的句点

    【讨论】:

      【解决方案3】:

      我想添加以下内容:

      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));
      }
      

      【讨论】:

        【解决方案4】:

        使用函数isNaN。我相信如果您测试!isNaN(yourstringhere),它适用于任何这些情况。

        【讨论】:

          【解决方案5】:

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

          虽然结果与您要查找的结果有些不同 (try it):

                                                        // 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
          

          【讨论】:

            【解决方案6】:

            可以不用RegExp as

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

            【讨论】:

              【解决方案7】:

              啊!不要听正则表达式的答案。 RegEx 对此很讨厌,我说的不仅仅是性能。用你的正则表达式制作微妙的、不可能的错误是很容易的。

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

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

              它是这样工作的:

              (input - 0) 表达式强制 JavaScript 对您的输入值进行类型强制;它必须首先被解释为减法运算的数字。如果转换为数字失败,则表达式将生成NaN。然后将此 numeric 结果与您传入的原始值进行比较。由于左侧现在是数字,因此再次使用类型强制。既然双方的输入都从相同的原始值强制转换为相同的类型,您会认为它们应该始终相同(始终为真)。但是,有一条特殊规则说NaN 永远不会等于NaN,因此不能转换为数字的值(并且只有不能转换为数字的值)将导致 false。

              长度检查是针对涉及空字符串的特殊情况。另请注意,它落在您的 0x89f 测试中,但这是因为在许多环境中,这是定义数字文字的好方法。如果您想捕捉该特定情况,您可以添加额外的检查。更好的是,如果这是您不使用 isNaN() 的原因,那么只需将您自己的函数包裹在 isNaN() 周围,它也可以进行额外的检查。

              综上所述,如果你想知道一个值是否可以转换为数字,实际上尝试将其转换为数字。


              我回去做了一些研究为什么空白字符串没有预期的输出,我想我现在明白了:一个空字符串被强制转换为0而不是@987654330 @。只需在长度检查之前修剪字符串即可处理这种情况。

              对新代码运行单元测试,它只会在无穷大和布尔文字上失败,唯一应该是问题的时间是如果你正在生成代码(真的,谁会输入文字并检查是否它是数字?你应该知道),那会是一些奇怪的代码。

              但是,再次使用它的唯一原因是,如果由于某种原因您必须避免使用 isNaN()。

              【讨论】:

                【解决方案8】:

                Yahoo! UI 使用这个:

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

                【讨论】:

                  【解决方案9】:
                  function IsNumeric(num) {
                       return (num >=0 || num < 0);
                  }
                  

                  这也适用于 0x23 类型的数字。

                  【讨论】:

                    【解决方案10】:

                    @Joel's answer 非常接近,但在以下情况下会失败:

                    // 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; 但@ 987654335@ 不应被视为"numeric")。

                    我认为值得分享这组+30 unit tests 用于众多功能实现,并分享通过我所有测试的那一个:

                    function isNumeric(n) {
                        return !isNaN(parseFloat(n)) && isFinite(n);
                    }
                    

                    P.S. isNaNisFinite 由于强制转换为数字而具有令人困惑的行为。在 ES6 中,Number.isNaNNumber.isFinite 将解决这些问题。使用它们时请记住这一点。


                    更新Here's how jQuery does it now (2.2-stable)

                    isNumeric: function(obj) {
                        var realStringObj = obj && obj.toString();
                        return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;
                    }
                    

                    更新Angular 4.3:

                    export function isNumeric(value: any): boolean {
                        return !isNaN(value - parseFloat(value));
                    }
                    

                    【讨论】:

                    • jsBench 说,angulars isNumeric 比 isNaN && isFinite 函数快 0.51%。有人可以证实吗?没有注册就无法分享我的测试...
                    【解决方案11】:

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

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

                    【讨论】:

                    • 不幸的是,这是一种严格的数字检查器,对于仅包含数字字母的任何字符串(如“0”等)都会失败...
                    【解决方案12】:

                    这应该可行。这里提供的一些功能有缺陷,也应该比这里的任何其他功能都快。

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

                    解释:

                    自己创建一个副本,然后把数字转换成float,然后和原来的数字比较,如果还是数字,(无论是整数还是浮点数),和原来的数字相匹配,即确实是一个数字。

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

                    警告:使用风险自负,不保证。

                    【讨论】:

                      【解决方案13】:

                      以下方法也可以。

                      function isNumeric(v) {
                               return v.length > 0 && !isNaN(v) && v.search(/[A-Z]|[#]/ig) == -1;
                         };
                      

                      【讨论】:

                        【解决方案14】:
                        return (input - 0) == input && input.length > 0;
                        

                        对我不起作用。当我发出警报并进行测试时,input.lengthundefined。我认为没有属性可以检查整数长度。所以我做的是

                        var temp = '' + input;
                        return (input - 0) == input && temp.length > 0;
                        

                        效果很好。

                        【讨论】:

                          【解决方案15】:

                          我的解决方案,

                          function isNumeric(input) {
                              var number = /^\-{0,1}(?:[0-9]+){0,1}(?:\.[0-9]+){0,1}$/i;
                              var regex = RegExp(number);
                              return regex.test(input) && input.length>0;
                          }
                          

                          它似乎在任何情况下都有效,但我可能错了。

                          【讨论】:

                            【解决方案16】:

                            可以通过以下方式验证整数值:

                            function isNumeric(value) {
                                var bool = isNaN(+value));
                                bool = bool || (value.indexOf('.') != -1);
                                bool = bool || (value.indexOf(",") != -1);
                                return !bool;
                            };
                            

                            这种方式更简单快捷!已检查所有测试!

                            【讨论】:

                              【解决方案17】:

                              @Zoltan Lengyel '其他语言环境'评论(4 月 26 日 2:14)@CMS 12 月回答(2009 年 2 月 5:36):

                              我建议测试typeof (n) === 'string'

                                  function isNumber(n) {
                                      if (typeof (n) === 'string') {
                                          n = n.replace(/,/, ".");
                                      }
                                      return !isNaN(parseFloat(n)) && isFinite(n);
                                  }
                              

                              这扩展了 Zoltans 的建议,使其不仅能够测试像 isNumber('12,50') 这样的“本地化数字”,而且还能够测试像 isNumber(2011) 这样的“纯”数字。

                              【讨论】:

                                【解决方案18】:

                                嗯,我正在使用我制作的这个......

                                到目前为止一直有效:

                                function checkNumber(value) {
                                    if ( value % 1 == 0 )
                                        return true;
                                    else
                                        return false;
                                }
                                

                                如果您发现任何问题,请告诉我。

                                就像任何数字都应该被一整除一样,我想我可以只使用这个模块,如果你尝试将一个字符串分成一个数字,结果就不会是这样。所以。

                                【讨论】:

                                • 1.5 怎么样?此外,函数体有很多冗余代码。您应该直接返回表达式的结果,这将是一个布尔值。
                                【解决方案19】:

                                如果我没记错的话,这应该匹配任何有效的 JavaScript 数值,不包括常量(InfinityNaN)和符号运算符+/-(因为它们实际上不是就我而言,它们是独立的运营商):

                                我需要这个用于分词器,在这种情况下,将数字发送到 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
                                

                                【讨论】:

                                  【解决方案20】:

                                  我正在使用更简单的解决方案:

                                  function isNumber(num) {
                                      return parseFloat(num).toString() == num
                                  }
                                  

                                  【讨论】:

                                  • 这最终会在任何带有多余 0 的情况下失败。示例:“10.0”
                                  【解决方案21】:

                                  在这里,我从这个页面收集了“好的”,并将它们放入一个简单的测试模式供您自己评估。

                                  对于新手,console.log 是一个内置函数(适用于所有现代浏览器),可让您将结果输出到 JavaScript 控制台(四处寻找,您会发现),而不必输出到 HTML 页面.

                                  var isNumeric = function(val){
                                      // --------------------------
                                      // Recommended
                                      // --------------------------
                                  
                                      // jQuery - works rather well
                                      // See CMS's unit test also: http://dl.getdropbox.com/u/35146/js/tests/isNumber.html
                                      return !isNaN(parseFloat(val)) && isFinite(val);
                                  
                                      // Aquatic - good and fast, fails the "0x89f" test, but that test is questionable.
                                      //return parseFloat(val)==val;
                                  
                                      // --------------------------
                                      // Other quirky options
                                      // --------------------------
                                      // Fails on "", null, newline, tab negative.
                                      //return !isNaN(val);
                                  
                                      // user532188 - fails on "0x89f"
                                      //var n2 = val;
                                      //val = parseFloat(val);
                                      //return (val!='NaN' && n2==val);
                                  
                                      // Rafael - fails on negative + decimal numbers, may be good for isInt()?
                                      // return ( val % 1 == 0 ) ? true : false;
                                  
                                      // pottedmeat - good, but fails on stringy numbers, which may be a good thing for some folks?
                                      //return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(val);
                                  
                                      // Haren - passes all
                                      // borrowed from http://www.codetoad.com/javascript/isnumeric.asp
                                      //var RE = /^-{0,1}\d*\.{0,1}\d+$/;
                                      //return RE.test(val);
                                  
                                      // YUI - good for strict adherance to number type. Doesn't let stringy numbers through.
                                      //return typeof val === 'number' && isFinite(val);
                                  
                                      // user189277 - fails on "" and "\n"
                                      //return ( val >=0 || val < 0);
                                  }
                                  
                                  var tests = [0, 1, "0", 0x0, 0x000, "0000", "0x89f", 8e5, 0x23, -0, 0.0, "1.0", 1.0, -1.5, 0.42, '075', "01", '-01', "0.", ".0", "a", "a2", true, false, "#000", '1.2.3', '#abcdef', '', "", "\n", "\t", '-', null, undefined];
                                  
                                  for (var i=0; i<tests.length; i++){
                                      console.log( "test " + i + ":    " + tests[i] + "    \t   " + isNumeric(tests[i]) );
                                  }
                                  

                                  【讨论】:

                                    【解决方案22】:

                                    从 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 是一个有效数字(十六进制)

                                    【讨论】:

                                      【解决方案23】:

                                      接受的答案未通过您的 #7 测试,我想这是因为您改变了主意。所以这是对已接受答案的回应,我对此有疑问。

                                      在一些项目中,我需要验证一些数据,并尽可能确定它是一个可用于数学运算的 javascript 数值。

                                      jQuery 和其他一些 javascript 库已经包含这样的函数,通常称为 isNumeric。还有一个post on stackoverflow 已被广泛接受为答案,与上述库使用的通用例程相同。

                                      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 test cases 并克隆了 testing on 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), "Exponential notation");
                                            ok(isNumber("123e-2"), "Exponential notation string");
                                          });
                                      
                                          test("Non-Numeric values", function() {
                                            equals(isNumber(""), false, "Empty string");
                                            equals(isNumber("        "), false, "Whitespace characters string");
                                            equals(isNumber("\t\t"), false, "Tab characters string");
                                            equals(isNumber("abcdefghijklm1234567890"), false, "Alphanumeric character string");
                                            equals(isNumber("xabcdefx"), false, "Non-numeric character string");
                                            equals(isNumber(true), false, "Boolean true literal");
                                            equals(isNumber(false), false, "Boolean false literal");
                                            equals(isNumber("bcfed5.2"), false, "Number with preceding non-numeric characters");
                                            equals(isNumber("7.2acdgs"), false, "Number with trailling non-numeric characters");
                                            equals(isNumber(undefined), false, "Undefined value");
                                            equals(isNumber(null), false, "Null value");
                                            equals(isNumber(NaN), false, "NaN value");
                                            equals(isNumber(Infinity), false, "Infinity primitive");
                                            equals(isNumber(Number.POSITIVE_INFINITY), false, "Positive Infinity");
                                            equals(isNumber(Number.NEGATIVE_INFINITY), false, "Negative Infinity");
                                            equals(isNumber(new Date(2009, 1, 1)), false, "Date object");
                                            equals(isNumber(new Object()), false, "Empty object");
                                            equals(isNumber(function() {}), false, "Instance of a function");
                                            equals(isNumber([]), false, "Empty Array");
                                            equals(isNumber(["-10"]), false, "Array Negative integer string");
                                            equals(isNumber(["0"]), false, "Array Zero string");
                                            equals(isNumber(["5"]), false, "Array Positive integer string");
                                            equals(isNumber([-16]), false, "Array Negative integer number");
                                            equals(isNumber([0]), false, "Array Zero integer number");
                                            equals(isNumber([32]), false, "Array Positive integer number");
                                            equals(isNumber(["040"]), false, "Array Octal integer literal string");
                                            equals(isNumber([0144]), false, "Array Octal integer literal");
                                            equals(isNumber(["-040"]), false, "Array Negative Octal integer literal string");
                                            equals(isNumber([-0144]), false, "Array Negative Octal integer literal");
                                            equals(isNumber(["0xFF"]), false, "Array Hexadecimal integer literal string");
                                            equals(isNumber([0xFFF]), false, "Array Hexadecimal integer literal");
                                            equals(isNumber(["-0xFF"]), false, "Array Negative Hexadecimal integer literal string");
                                            equals(isNumber([-0xFFF]), false, "Array Negative Hexadecimal integer literal");
                                            equals(isNumber([1, 2]), false, "Array with more than 1 Positive interger number");
                                            equals(isNumber([-1, -2]), false, "Array with more than 1 Negative interger number");
                                          });
                                        }
                                      
                                        var functionsToTest = [
                                      
                                          function(n) {
                                            return !isNaN(parseFloat(n)) && isFinite(n);
                                          },
                                      
                                          function(n) {
                                            return !isNaN(n) && !isNaN(parseFloat(n));
                                          },
                                      
                                          function(n) {
                                            return !isNaN((n));
                                          },
                                      
                                          function(n) {
                                            return !isNaN(parseFloat(n));
                                          },
                                      
                                          function(n) {
                                            return typeof(n) != "boolean" && !isNaN(n);
                                          },
                                      
                                          function(n) {
                                            return parseFloat(n) === Number(n);
                                          },
                                      
                                          function(n) {
                                            return parseInt(n) === Number(n);
                                          },
                                      
                                          function(n) {
                                            return !isNaN(Number(String(n)));
                                          },
                                      
                                          function(n) {
                                            return !isNaN(+('' + n));
                                          },
                                      
                                          function(n) {
                                            return (+n) == n;
                                          },
                                      
                                          function(n) {
                                            return n && /^-?\d+(\.\d+)?$/.test(n + '');
                                          },
                                      
                                          function(n) {
                                            return isFinite(Number(String(n)));
                                          },
                                      
                                          function(n) {
                                            return isFinite(String(n));
                                          },
                                      
                                          function(n) {
                                            return !isNaN(n) && !isNaN(parseFloat(n)) && isFinite(n);
                                          },
                                      
                                          function(n) {
                                            return parseFloat(n) == n;
                                          },
                                      
                                          function(n) {
                                            return (n - 0) == n && n.length > 0;
                                          },
                                      
                                          function(n) {
                                            return typeof n === 'number' && isFinite(n);
                                          },
                                      
                                          function(n) {
                                            return !Array.isArray(n) && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
                                          }
                                      
                                        ];
                                      
                                      
                                        // Examines the functionsToTest array, extracts the return statement of each function
                                        // and fills the toTest select element.
                                        var fillToTestSelect = function() {
                                          for (var i = 0; i < functionsToTest.length; i++) {
                                            var f = functionsToTest[i].toString();
                                            var option = /[\s\S]*return ([\s\S]*);/.exec(f)[1];
                                            $("#toTest").append('<option value="' + i + '">' + (i + 1) + '. ' + option + '</option>');
                                          }
                                        }
                                      
                                        var performTest = function(functionNumber) {
                                          reset(); // Reset previous test
                                          $("#tests").html(""); //Clean test results
                                          isNumber = functionsToTest[functionNumber]; // Override the isNumber global function with the one to test
                                          testSuite(); // Run the test
                                      
                                          // Get test results
                                          var totalFail = 0;
                                          var totalPass = 0;
                                          $("b.fail").each(function() {
                                            totalFail += Number($(this).html());
                                          });
                                          $("b.pass").each(function() {
                                            totalPass += Number($(this).html());
                                          });
                                          $("#testresult").html(totalFail + " of " + (totalFail + totalPass) + " test failed.");
                                      
                                          $("#banner").attr("class", "").addClass(totalFail > 0 ? "fail" : "pass");
                                        }
                                      
                                        return {
                                          performTest: performTest,
                                          fillToTestSelect: fillToTestSelect,
                                          testSuite: testSuite
                                        };
                                      }();
                                      
                                      
                                      $(document).ready(function() {
                                        testHelper.fillToTestSelect();
                                        testHelper.performTest(0);
                                      
                                        $("#toTest").change(function() {
                                          testHelper.performTest($(this).children(":selected").val());
                                        });
                                      });
                                      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
                                      <script src="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.js" type="text/javascript"></script>
                                      <link href="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.css" rel="stylesheet" type="text/css">
                                      <h1>isNumber Test Cases</h1>
                                      
                                      <h2 id="banner" class="pass"></h2>
                                      
                                      <h2 id="userAgent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11</h2>
                                      
                                      <div id="currentFunction"></div>
                                      
                                      <div id="selectFunction">
                                        <label for="toTest" style="font-weight:bold; font-size:Large;">Select function to test:</label>
                                        <select id="toTest" name="toTest">
                                        </select>
                                      </div>
                                      
                                      <div id="testCode"></div>
                                      
                                      <ol id="tests">
                                        <li class="pass">
                                          <strong>Integer Literals <b style="color:black;">(0, 10, 10)</b></strong>
                                      
                                          <ol style="display: none;">
                                            <li class="pass">Negative integer string</li>
                                      
                                            <li class="pass">Zero string</li>
                                      
                                            <li class="pass">Positive integer string</li>
                                      
                                            <li class="pass">Negative integer number</li>
                                      
                                            <li class="pass">Zero integer number</li>
                                      
                                            <li class="pass">Positive integer number</li>
                                      
                                            <li class="pass">Octal integer literal string</li>
                                      
                                            <li class="pass">Octal integer literal</li>
                                      
                                            <li class="pass">Hexadecimal integer literal string</li>
                                      
                                            <li class="pass">Hexadecimal integer literal</li>
                                          </ol>
                                        </li>
                                      
                                        <li class="pass">
                                          <strong>Foating-Point Literals <b style="color:black;">(0, 6, 6)</b></strong>
                                      
                                          <ol style="display: none;">
                                            <li class="pass">Negative floating point string</li>
                                      
                                            <li class="pass">Positive floating point string</li>
                                      
                                            <li class="pass">Negative floating point number</li>
                                      
                                            <li class="pass">Positive floating point number</li>
                                      
                                            <li class="pass">Exponential notation</li>
                                      
                                            <li class="pass">Exponential notation string</li>
                                          </ol>
                                        </li>
                                      
                                        <li class="pass">
                                          <strong>Non-Numeric values <b style="color:black;">(0, 18, 18)</b></strong>
                                      
                                          <ol style="display: none;">
                                            <li class="pass">Empty string: false</li>
                                      
                                            <li class="pass">Whitespace characters string: false</li>
                                      
                                            <li class="pass">Tab characters string: false</li>
                                      
                                            <li class="pass">Alphanumeric character string: false</li>
                                      
                                            <li class="pass">Non-numeric character string: false</li>
                                      
                                            <li class="pass">Boolean true literal: false</li>
                                      
                                            <li class="pass">Boolean false literal: false</li>
                                      
                                            <li class="pass">Number with preceding non-numeric characters: false</li>
                                      
                                            <li class="pass">Number with trailling non-numeric characters: false</li>
                                      
                                            <li class="pass">Undefined value: false</li>
                                      
                                            <li class="pass">Null value: false</li>
                                      
                                            <li class="pass">NaN value: false</li>
                                      
                                            <li class="pass">Infinity primitive: false</li>
                                      
                                            <li class="pass">Positive Infinity: false</li>
                                      
                                            <li class="pass">Negative Infinity: false</li>
                                      
                                            <li class="pass">Date object: false</li>
                                      
                                            <li class="pass">Empty object: false</li>
                                      
                                            <li class="pass">Instance of a function: false</li>
                                          </ol>
                                        </li>
                                      </ol>
                                      
                                      <div id="main">
                                        This page contains tests for a set of isNumber functions. To see them, take a look at the source.
                                      </div>
                                      
                                      <div>
                                        <p class="result">Tests completed in 0 milliseconds.
                                          <br>0 tests of 0 failed.</p>
                                      </div>

                                      【讨论】:

                                        【解决方案24】:

                                        knockoutJs Inbuild 库验证函数

                                        通过扩展它,该字段得到验证

                                        1) 数字

                                        self.number = ko.observable(numberValue).extend({ 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.observable(numberValue).extend({ 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 = ko.observable(numberValue).extend({ min: 5}).extend({ max: 10});

                                        此字段只接受 5 到 10 之间的值

                                        测试用例

                                        numberValue = '5'    --> true
                                        numberValue = '6'    --> true
                                        numberValue = '6.5'  --> true
                                        numberValue = '9'    --> true
                                        numberValue = '11'   --> false
                                        numberValue = '0'    --> false
                                        numberValue = ''    --> false
                                        

                                        【讨论】:

                                          【解决方案25】:

                                          @CMS' answer: 你的 sn-p 在我的机器上使用 nodejs 的空白情况下失败了。所以我将它与 @joel's answer 到以下地址:

                                          is_float = function(v) {
                                              return !isNaN(v) && isFinite(v) &&
                                                  (typeof(v) == 'number' || v.replace(/^\s+|\s+$/g, '').length > 0);
                                          }
                                          

                                          我用那些浮动的案例对它进行了单元测试:

                                          var t = [
                                                  0,
                                                  1.2123,
                                                  '0',
                                                  '2123.4',
                                                  -1,
                                                  '-1',
                                                  -123.423,
                                                  '-123.432',
                                                  07,
                                                  0xad,
                                                  '07',
                                                  '0xad'
                                              ];
                                          

                                          以及那些没有浮点数的情况(包括空白和对象/数组):

                                              var t = [
                                                  'hallo',
                                                  [],
                                                  {},
                                                  'jklsd0',
                                                  '',
                                                  "\t",
                                                  "\n",
                                                  ' '
                                              ];
                                          

                                          这里一切正常。也许这会有所帮助。

                                          可以在here找到完整的源代码。

                                          【讨论】:

                                            【解决方案26】:

                                            这是我使用的一个小改进版本(可能是最快的方法),而不是确切的 jQuery 变体,我真的不知道他们为什么不使用这个:

                                            function isNumeric(val) {
                                                return !isNaN(+val) && isFinite(val);
                                            }
                                            

                                            jQuery 版本的缺点是,如果您传递带有前导数字和尾随字母的字符串,例如 "123abc"parseFloat | parseInt 将提取数字分数并返回 123,但是,第二个守卫 isFinite 将失败反正。 使用一元 + 运算符,它将死在第一个后卫上,因为 + 为此类混合体抛出 NaN :) 有一点性能,但我认为语义增益很可靠。

                                            【讨论】:

                                            • 当心一元 '+' 将在对象上调用 valueOf() - 请参阅jsfiddle。同样,前导空格也失败了,领先的答案也是如此。
                                            【解决方案27】:

                                            我对@CMS 的answer 的唯一问题是排除了NaN 和Infinity,它们在许多情况下都是有用的数字。检查NaN 的一种方法是检查不等于自身的数值NaN != NaN!所以你真的要处理 3 个测试...

                                            function isNumber(n) {
                                              n = parseFloat(n);
                                              return !isNaN(n) || n != n;
                                            }
                                            function isFiniteNumber(n) {
                                              n = parseFloat(n);
                                              return !isNaN(n) && isFinite(n);
                                            }    
                                            function isComparableNumber(n) {
                                              n = parseFloat(n);
                                              return (n >=0 || n < 0);
                                            }
                                            
                                            isFiniteNumber('NaN')
                                            false
                                            isFiniteNumber('OxFF')
                                            true
                                            isNumber('NaN')
                                            true
                                            isNumber(1/0-1/0)
                                            true
                                            isComparableNumber('NaN')
                                            false
                                            isComparableNumber('Infinity')
                                            true
                                            

                                            我的 isComparableNumber 非常接近另一个优雅的answer,但可以处理数字的十六进制和其他字符串表示形式。

                                            【讨论】:

                                              【解决方案28】:

                                              我找到了简单的解决方案,可能不是最好的,但效果很好:)

                                              接下来,我将字符串解析为 Int 并检查现在为 int 类型的新变量的长度大小是否与原始字符串变量的长度相同。从逻辑上讲,如果大小相同,则意味着字符串已完全解析为 int,并且仅当字符串仅由数字“制成”时才有可能。

                                              var val=1+$(e).val()+'';
                                              var n=parseInt(val)+'';
                                              if(val.length == n.length )alert('Is int');
                                              

                                              您可以轻松地将该代码放入函数中,而不是使用警报使用 return true if int。 请记住,如果您在字符串中使用点或逗号,您正在检查它仍然是假的,因为您正在解析为 int。

                                              注意:在 e.val 上添加 1+,因此不会删除从零开始的内容。

                                              【讨论】:

                                                【解决方案29】:

                                                我在下面运行了以下命令,它通过了所有测试用例...

                                                它利用parseFloatNumber 处理输入的不同方式...

                                                function IsNumeric(_in) {
                                                    return (parseFloat(_in) === Number(_in) && Number(_in) !== NaN);
                                                }
                                                

                                                【讨论】:

                                                • 我没有尝试过这个,但只是一个提示:你可以减少它只返回 if 表达式,例如return parseFloat...
                                                • @Michael Haren,我傻了,我刚刚看到这个链接http://dl.dropboxusercontent.com/u/35146/js/tests/isNumber.html 获得了最高的支持(大约 30 多个测试用例),解释了很多......
                                                • 这是错误的,你不能用=====!=!==与NaN进行比较,它总是返回false。
                                                • NaN 的棘手之处在于它不等于每个 JavaScript 值,包括它自己。所以anythingAtAll === NaN 是假的,anythingAtAll !== NaN 是真的。测试 NaN 的方法是将一个值与其自身进行比较:如果 x 为 NaN,x !== x 为真,否则为假。
                                                • @jkdev 你也可以使用isNaN(NaN),它会返回true。这是 JavaScript 的内置函数。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
                                                【解决方案30】:

                                                以下似乎适用于许多情况:

                                                function isNumeric(num) {
                                                    return (num > 0 || num === 0 || num === '0' || num < 0) && num !== true && isFinite(num);
                                                }
                                                

                                                这是建立在这个答案之上的(也适用于这个答案): https://stackoverflow.com/a/1561597/1985601

                                                【讨论】:

                                                  猜你喜欢
                                                  • 2011-01-30
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 2014-04-30
                                                  • 1970-01-01
                                                  相关资源
                                                  最近更新 更多