关于数字验证:在JavaScript中验证decimal数 – IsNumeric()

Validate decimal numbers in JavaScript - IsNumeric()

在javascript中验证十进制数字最干净、最有效的方法是什么?

奖励积分:

  • 清晰。溶液应干净、简单。
  • 跨平台。
  • 测试用例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Whitespace strings:
    IsNumeric(' ')    == true;
    IsNumeric('\t\t') == true;
    IsNumeric('

    '
    ) == true;

    // Number literals:
    IsNumeric(-1)  == false;
    IsNumeric(0)   == false;
    IsNumeric(1.1) == false;
    IsNumeric(8e5) == false;

    一段时间以前,我必须实现一个IsNumeric函数,以查明一个变量是否包含一个数值,不管它的类型如何,它可能是一个String包含一个数值(我还必须考虑指数记数法等),一个Number对象,实际上任何东西都可以传递给这个函数,我不能使任何类型注意类型强制(如+true == 1;,但true不应视为"numeric")。

    我认为值得分享这组对许多函数实现所做的+30单元测试,也值得分享通过我所有测试的测试:

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

    由于强制转换为数字,P.S.isnan&isfemit具有令人困惑的行为。在ES6中,number.isnan&number.isfemited将解决这些问题。使用时请记住这一点。

    更新:下面是jquery现在的工作方式(2.2-stable):

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

    更新:角度4.3:

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


    哎呀!不要听正则表达式的答案。雷杰克斯对此很讨厌,我说的不仅仅是表演。用正则表达式很容易做出细微的、不可能发现错误的错误。

    如果您不能使用isNaN(),这应该会更好地工作:

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

    它的工作原理如下:

    (input - 0)表达式强制javascript对输入值执行类型强制;必须首先将其解释为减法运算的数字。如果转换为数字失败,表达式将导致NaN。然后将此数值结果与传入的原始值进行比较。由于左侧现在是数字,因此再次使用类型强制。既然两边的输入都是从相同的原始值强制为相同的类型,那么您会认为它们应该总是相同的(总是正确的)。但是,有一个特殊的规则说,NaN永远不等于NaN,因此无法转换为数字的值(并且只有无法转换为数字的值)将导致错误。

    对长度的检查适用于涉及空字符串的特殊情况。还要注意,它落在了您的0x89F测试上,但这是因为在许多环境中,这是定义数字文本的一种好方法。如果您想要捕捉那个特定的场景,可以添加一个额外的检查。更好的是,如果这是您不使用isNaN()的原因,那么只需将您自己的函数包装在isNaN()周围,这样也可以进行额外的检查。

    总之,如果您想知道某个值是否可以转换为数字,请尝试将其转换为数字。

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

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

    但是,同样,使用它的唯一原因是,出于某种原因,必须避免isan()。


    这种方法似乎很有效:

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

    并测试它:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // alert(TestIsNumeric());

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

        return results;
    }

    我从http://www.codetoad.com/javascript/isnumeric.asp借用了这个regex。说明:

    1
    2
    3
    4
    5
    6
    /^ 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


    雅虎!UI使用:

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


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

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


    被接受的答案没有通过你的测试,我猜是因为你改变了主意。所以这是对公认答案的回应,我对此有异议。

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

    jquery和其他一些javascript库已经包含了这样一个函数,通常称为isNumeric。还有一个关于stackoverflow的帖子被广泛接受作为答案,与前面提到的库使用的常规程序相同。

    1
    2
    3
    function isNumber(n) {
      return !isNaN(parseFloat(n)) && isFinite(n);
    }

    首先,如果参数是长度为1的数组,并且单个元素的类型被上述逻辑视为数字,那么上面的代码将返回true。在我看来,如果它是一个数组,那么它不是数字。

    为了解决这个问题,我从逻辑中向折扣数组添加了一个检查

    1
    2
    3
    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)被视为数字。我需要两者都是有效的数字。

    然后我修改了逻辑以考虑到这一点。

    1
    2
    3
    function isNumber(n) {
      return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
    }

    如果您担心每次调用函数时都会创建regex,那么您可以在一个闭包中重写它,类似于这样

    1
    2
    3
    4
    5
    6
    7
    var isNumber = (function () {
      var rx = /^-/;

      return function (n) {
          return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
      };
    }());

    然后我取了CMSS+30测试用例,在jsFiddle上克隆了测试,添加了我的额外测试用例和我上面描述的解决方案。

    它可能无法取代广为接受/使用的答案,但如果这更多的是您期望的结果,从您的isNumeric函数,那么希望这将是一些帮助。

    编辑:正如Bergi所指出的,还有其他可能被认为是数字的对象,白名单比黑名单更好。考虑到这一点,我将增加标准。

    我希望isNumeric函数只考虑数字或字符串

    考虑到这一点,最好使用

    1
    2
    3
    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(/^-/, ''));
    }

    测试解决方案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    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());
      });
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript">
    <script src="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.js" type="text/javascript">
    <link href="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.css" rel="stylesheet" type="text/css">
    isNumber Test Cases

    <h2 id="banner" class="pass">

    <h2 id="userAgent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11




      <label for="toTest" style="font-weight:bold; font-size:Large;">Select function to test:</label>
      <select id="toTest" name="toTest">
      </select>





      <li class="pass">
        Integer Literals <b style="color:black;">(0, 10, 10)

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

       
     
    </li>


      <li class="pass">
        Foating-Point Literals <b style="color:black;">(0, 6, 6)

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

       
     
    </li>


      <li class="pass">
        Non-Numeric values <b style="color:black;">(0, 18, 18)

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

       
     
    </li>




      This page contains tests for a set of isNumber functions. To see them, take a look at the source.



      <p class="result">Tests completed in 0 milliseconds.
        0 tests of 0 failed.
    </p>


    是的,内置的isNaN(object)比任何regex解析都快得多,因为它是内置和编译的,而不是动态解释的。

    虽然结果与您要查找的结果有些不同(尝试一下):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
                                                  // 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

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


    由于jquery 1.7,可以使用jQuery.isNumeric()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $.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是一个有效数字(hexa)


    它可以在没有regexp as的情况下完成

    1
    2
    3
    function IsNumeric(data){
        return parseFloat(data)==data;
    }


    我知道原来的问题没有提到jquery,但是如果你使用jquery,你可以做到:

    1
    $.isNumeric(val)

    简单。

    https://api.jquery.com/jquery.isnumeric/(自jquery 1.7起)


    1
    return (input - 0) == input && input.length > 0;

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

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

    效果很好。


    如果我没有弄错,这应该与任何有效的javascript数字值相匹配,不包括常量(InfinityNaN)和符号运算符+/-(因为它们实际上不是数字的一部分,就我而言,它们是独立的运算符):

    我需要一个标记器,在那里把数字发送到javascript进行评估不是一个选择…它绝对不是最短的正则表达式,但我相信它捕捉到了javascript数字语法的所有细微之处。

    1
    2
    /^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d))
    (?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i

    有效数字包括:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     - 0
     - 00
     - 01
     - 10
     - 0e1
     - 0e01
     - .0
     - 0.
     - .0e1
     - 0.e1
     - 0.e00
     - 0xf
     - 0Xf

    无效的数字将是

    1
    2
    3
    4
    5
    6
     - 00e1
     - 01e1
     - 00.0
     - 00x0
     - .
     - .e0

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

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


    对于@cms的答案,我唯一的问题是排除了NaN和无穷大,它们在许多情况下都是有用的数字。检查NaN的一种方法是检查不相等的数值,NaN != NaN!所以有三个测试你真的想处理…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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非常接近另一个优雅的答案,但它处理十六进制和其他数字的字符串表示。


    我想增加以下内容:

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

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

    1
    2
    3
    4
    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));
    }


    这里有一个lil位的改进版本(可能是最快的方法),我使用它来代替jquery的精确变体,我真的不知道他们为什么不使用这个版本:

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

    jquery版本的缺点是,如果传递一个带有前导数字和尾随字母的字符串(如"123abc"parseFloat | parseInt将提取数字分数并返回123,但第二个保护器isFinite无论如何都会使其失败。有了一元+操作器,它将死在第一个守卫上,因为+为这种混合动力车扔了NaN:)有一点表现,但我认为一个坚实的语义增益。


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

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

    这条路越来越容易!检查所有测试!


    我的解决方案,

    1
    2
    3
    4
    5
    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;
    }

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


    这应该有效。这里提供的一些函数是有缺陷的,也应该比这里的任何其他函数都快。

    1
    2
    3
    4
    5
    6
            function isNumeric(n)
            {
                var n2 = n;
                n = parseFloat(n);
                return (n!='NaN' && n2==n);
            }

    解释:

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

    它适用于数字字符串和普通数字。不适用于十六进制数。

    警告:请自行承担风险,不提供任何保证。


    检查变量是否包含有效数字只是一个看起来像数字的字符串,可以使用Number.isFinite(value)

    这是语言的一部分,因为ES2015

    实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Number.isFinite(Infinity)   // false
    Number.isFinite(NaN)        // false
    Number.isFinite(-Infinity)  // false

    Number.isFinite(0)          // true
    Number.isFinite(2e64)       // true

    Number.isFinite('0')        // false
    Number.isFinite(null)       // false


    要添加的几个测试:

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

    我想到了这个:

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

    解决方案包括:

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

    没有一个答案返回空字符串的false,这是一个修正…

    1
    2
    3
    4
    function is_numeric(n)
    {
     return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
    }

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

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


    您可以通过许多方式最小化此函数,还可以使用自定义regex实现负值或自定义图表:

    1
    2
    3
    4
    5
    6
    7
    $('.number').on('input',function(){
        var n=$(this).val().replace(/ /g,'').replace(/\D/g,'');
        if (!$.isNumeric(n))
            $(this).val(n.slice(0, -1))
        else
            $(this).val(n)
    });

    1
    2
    3
    function inNumeric(n){
       return Number(n).toString() === n;
    }

    如果n是数字,Number(n)将返回数值,toString()将返回字符串。但如果n不是数字,那么Number(n)将返回NaN,因此它将与原始n不匹配。


    我认为parsefloat函数可以在这里完成所有的工作。下面的函数通过了本页的所有测试,包括isNumeric(Infinity) == true

    1
    2
    3
    4
    function isNumeric(n) {

        return parseFloat(n) == n;
    }


    我知道这个问题已经回答了很多次了,但是下面是一个不错的候选人,在某些情况下是有用的。

    应该注意的是,它假定".42"不是数字,而"4."不是数字,因此应该考虑到这一点。

    1
    2
    3
    4
    5
    6
    7
    function isDecimal(x) {
      return '' + x === '' + +x;
    }

    function isInteger(x) {
      return '' + x === '' + parseInt(x);
    }

    isDecimal通过以下测试:

    1
    2
    3
    4
    5
    function testIsNumber(f) {
      return f('-1') && f('-1.5') && f('0') && f('0.42')
        && !f('.42') && !f('99,999') && !f('0x89f')
        && !f('#abcdef') && !f('1.2.3') && !f('') && !f('blah');
    }

    这里的想法是,每个数字或整数都有一个"规范的"字符串表示,并且应该拒绝每个非规范的表示。所以我们将其转换为一个数字并返回,看看结果是否是原始字符串。

    这些函数是否对您有用取决于用例。一个特点是不同的字符串代表不同的数字(如果两者都通过了isNumber()测试)。

    这是相关的,例如,作为对象属性名称的数字。

    1
    2
    3
    4
    var obj = {};
    obj['4'] = 'canonical 4';
    obj['04'] = 'alias of 4';
    obj[4];  // prints 'canonical 4' to the console.

    knockoutjs内置库验证函数

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

    1)数

    self.number = ko.observable(numberValue).扩展(数字:真);

    测试用例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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).扩展(数字:真);

    测试用例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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)min和max

    self.number = ko.observable(numberValue)。扩展(最小:5)。扩展(最大:10);

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

    测试用例

    1
    2
    3
    4
    5
    6
    7
    numberValue = '5'    --> true
    numberValue = '6'    --> true
    numberValue = '6.5'  --> true
    numberValue = '9'    --> true
    numberValue = '11'   --> false
    numberValue = '0'    --> false
    numberValue = ''    --> false

    您可以使用类型检查库,如https://github.com/arasasasayagin/is.js,或者从中提取检查片段(https://github.com/arasasasasayagin/is.js/blob/master/is.js_l131):

    1
    2
    3
    4
    5
    6
    7
    is.nan = function(value) {    // NaN is number :)
      return value !== value;
    };
     // is a given value number?
    is.number = function(value) {
        return !is.nan(value) && Object.prototype.toString.call(value) === '[object Number]';
    };

    一般来说,如果您需要它来验证参数类型(在函数调用的入口点),您可以使用符合JSDoc的契约(https://www.npmjs.com/package/bycontract):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /**
     * This is JSDOC syntax
     * @param {number|string} sum
     * @param {Object.<string, string>} payload
     * @param {function} cb
     */

    function foo( sum, payload, cb ) {
      // Test if the contract is respected at entry point
      byContract( arguments, ["number|string","Object.<string, string>","function" ] );
    }
    // Test it
    foo( 100, { foo:"foo" }, function(){}); // ok
    foo( 100, { foo: 100 }, function(){}); // exception

    不需要使用额外的lib。

    1
    2
    3
    const IsNumeric = (...numbers) => {
      return numbers.reduce((pre, cur) => pre && !!(cur === 0 || +cur), true);
    };

    试验

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    > IsNumeric(1)
    true
    > IsNumeric(1,2,3)
    true
    > IsNumeric(1,2,3,0)
    true
    > IsNumeric(1,2,3,0,'')
    false
    > IsNumeric(1,2,3,0,'2')
    true
    > IsNumeric(1,2,3,0,'200')
    true
    > IsNumeric(1,2,3,0,'-200')
    true
    > IsNumeric(1,2,3,0,'-200','.32')
    true

    我认为我的代码是完美的…

    1
    2
    3
    4
    5
    6
    7
    /**
     * @param {string} s
     * @return {boolean}
     */

    var isNumber = function(s) {
        return s.trim()!=="" && !isNaN(Number(s));
    };


    最好的方法如下:

    1
    2
    3
    function isThisActuallyANumber(data){
        return ( typeof data ==="number" && !isNaN(data) );
    }

    isNumeric=(el)=>{return Boolean(parseFloat(el)) && isFinite(el)}

    没有什么不同,但是我们可以使用布尔构造函数


    @CMS的答案:你的代码片段在我的机器上使用nodejs的空白案例中失败。所以我把它和@乔尔对以下问题的回答:

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

    我把它与那些浮动的情况结合起来进行了测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var t = [
            0,
            1.2123,
            '0',
            '2123.4',
            -1,
            '-1',
            -123.423,
            '-123.432',
            07,
            0xad,
            '07',
            '0xad'
        ];

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        var t = [
            'hallo',
            [],
            {},
            'jklsd0',
            '',
           "\t",
           "
    "
    ,
            ' '
        ];

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

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


    如果需要验证一组特殊的小数y您可以使用这个简单的javascript:

    http://codesheet.org/codesheet/x1ki7had

    1
    <input type="text" name="date" value="" pattern="[0-9]){1,2}(\.){1}([0-9]){2}" maxlength="6" placeholder="od npr.: 16.06" onchange="date(this);" />

    JavaScript:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function date(inputField) {        
      var isValid = /^([0-9]){1,2}(\.){1}([0-9]){2}$/.test(inputField.value);  
      if (isValid) {
        inputField.style.backgroundColor = '#bfa';
      } else {
        inputField.style.backgroundColor = '#fba';
      }
      return isValid;
    }

    1
    2
    3
    function isNumber(n) {
        return (n===n+''||n===n-0) && n*0==0 && /\S/.test(n);
    }

    说明:

    (n===n-0||n===n+'')验证n是数字还是字符串(丢弃数组、布尔值、日期、空值等)。您可以用n!==undefined && n!==null && (n.constructor===Number||n.constructor===String)替换(n===n-0||n===n+''):速度明显更快,但不那么简洁。

    n*0==0isFinite(n)那样验证n是否是有限数。如果需要检查表示负十六进制的字符串,只需将n*0==0替换为类似n.toString().replace(/^\s*-/,'')*0==0的内容。当然有点贵,所以如果你不需要它,就不要用它。

    /\S/.test(n)丢弃只包含空格的空字符串或字符串(在这种情况下,isFinite(n) or n*0==0返回一个false正数是必需的)。您可以使用(n!=0||/0/.test(n))而不是/\S/.test(n)来减少对.test(n)的调用次数,也可以使用稍快但不太简洁的测试,如(n!=0||(n+'').indexOf('0')>=0):微小的改进。


    在许多情况下,以下内容似乎可以正常工作:

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

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


    我运行了下面的程序,它通过了所有的测试用例…

    它利用了不同的方式来处理parseFloatNumber的输入…

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


    通过利用语言的动态类型检查,一个简单而干净的解决方案:

    1
    2
    3
    4
    5
    6
    function IsNumeric (string) {
       if(string === ' '.repeat(string.length)){
         return false
       }
       return string - 0 === string * 1
    }

    如果你不在乎空白,你可以删除"如果"

    参见下面的测试用例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function IsNumeric (string) {
       if(string === ' '.repeat(string.length)){
          return false
       }
       return string - 0 === string * 1
    }


    console.log('-1' + ' → ' + IsNumeric('-1'))    
    console.log('-1.5' + ' → ' + IsNumeric('-1.5'))
    console.log('0' + ' → ' + IsNumeric('0'))    
    console.log('0.42' + ' → ' + IsNumeric('0.42'))  
    console.log('.42' + ' → ' + IsNumeric('.42'))    
    console.log('99,999' + ' → ' + IsNumeric('99,999'))
    console.log('0x89f' + ' → ' + IsNumeric('0x89f'))  
    console.log('#abcdef' + ' → ' + IsNumeric('#abcdef'))
    console.log('1.2.3' + ' → ' + IsNumeric('1.2.3'))
    console.log('' + ' → ' + IsNumeric(''))    
    console.log('33 ' + ' → ' + IsNumeric('33 '))


    我找到了简单的解决方案,也许不是最好的,但它工作得很好:)

    接下来,我将把字符串解析为int,并检查新变量(现在是int类型)的长度大小是否与原始字符串变量的长度相同。逻辑上,如果大小相同,则意味着字符串被完全解析为int,并且只有在字符串仅由数字"构成"时才可能。

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

    您可以很容易地将该代码放入函数中,而不是使用alert,而是使用return true if int。记住,如果在字符串中使用点或逗号,则检查它是否仍然为假,因为您正在解析为int。

    注意:在e.val上添加1+,这样就不会删除起始零。


    我用这种方式来检查变量是否为数字:

    1
    v * 1 == v


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    function isNumeric(n) {
        var isNumber = true;

        $.each(n.replace(/ /g,'').toString(), function(i, v){
            if(v!=',' && v!='.' && v!='-'){
                if(isNaN(v)){
                   isNumber = false;
                   return false;
                }
             }
         });

        return isNumber;
    }

    isNumeric(-3,4567.89);   // true

    isNumeric(3,4567.89);   // true

    isNumeric("-3,4567.89");   // true

    isNumeric(3d,4567.89);   // false

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $('.rsval').bind('keypress', function(e){  
            var asciiCodeOfNumbers = [48,46, 49, 50, 51, 52, 53, 54, 54, 55, 56, 57];
            var keynum = (!window.event) ? e.which : e.keyCode;
            var splitn = this.value.split(".");
            var decimal = splitn.length;
            var precision = splitn[1];
            if(decimal == 2 && precision.length >= 2  ) { console.log(precision , 'e');   e.preventDefault(); }
            if( keynum == 46 ){  
                if(decimal > 2) { e.preventDefault(); }  
            }
            if ($.inArray(keynum, asciiCodeOfNumbers) == -1)
                e.preventDefault();    
      });


    @Zoltan Lengyel在@cms dec答案中的"其他地区"评论(4月26日2:14)(2009年2月5:36):

    我建议对typeof (n) === 'string'进行测试:

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

    这将佐尔坦的建议扩展到不仅能够测试像isNumber('12,50')这样的"局部数字",而且能够测试像isNumber(2011)这样的"纯"数字。


    嗯,我用的是我做的这个……

    到目前为止,它一直在工作:

    1
    2
    3
    4
    5
    6
    function checkNumber(value) {
        if ( value % 1 == 0 )
            return true;
        else
            return false;
    }

    如果你发现它有什么问题,请告诉我。

    就像任何数字都可以被一个整除而不剩下任何东西一样,我想我可以使用这个模块,如果你尝试将一个字符串分割成一个数字,结果就不会是这个了。所以。


    以下内容也可能有效。

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


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

    对于新手来说,console.log是一个内置的功能(在所有现代浏览器中都有),它允许您将结果输出到javascript控制台(您可以找到它),而不必输出到HTML页面。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    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"
    "
        //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', '',"","
    ","\t", '-', null, undefined];

    for (var i=0; i<tests.length; i++){
        console.log("
    test" + i +":   " + tests[i] +"    \t  " + isNumeric(tests[i]) );
    }