验证字符串是否为正整数

时间:2012-05-31 13:39:16

标签: javascript

我希望最简单的故障安全测试来检查JavaScript中的字符串是否为正整数。

isNaN(str)对于所有种类的非整数值都返回true,parseInt(str)返回浮点字符串的整数,如“2.5”。而且我也不想使用一些jQuery插件。

14 个答案:

答案 0 :(得分:270)

给你两个答案:

  • 基于解析

  • 正则表达式

请注意,在这两种情况下,我都将“正整数”解释为包含0,即使0不是正数。如果您想禁用0,我会添加备注。

基于解析

如果您希望它是一个合理范围的值的标准化十进制整数字符串,您可以这样做:

function isNormalInteger(str) {
    var n = Math.floor(Number(str));
    return n !== Infinity && String(n) === str && n >= 0;
}

Live testbed:

function isNormalInteger(str) {
    var n = Math.floor(Number(str));
    return String(n) === str && n >= 0;
}
function gid(id) {
  return document.getElementById(id);
}
function test(str, expect) {
  console.log(str + ": " + (isNormalInteger(str) ? "Yes" : "No"));
}
gid("btn").addEventListener(
  "click",
  function() {
    test(gid("text").value);
  },
  false
);
test("1");
test("1.23");
test("1234567890123");
test("1234567890123.1");
<label>
  String:
  <input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">

如果您想禁止0,只需将>= 0更改为> 0

如何运作:

  1. Number(str):将str转换为数字;该数字可能有一小部分,或者可能是NaN

  2. Math.floor:截断数字(删除任何小数部分)。

  3. String(...):将结果转换回普通的十进制字符串。对于非常大的数字,这将采用科学记数法,这可能会破坏这种方法。 (我不太清楚分裂的位置,the details are in the spec,但对于整数,我相信它已超过21位数[此时数字变得非常不精确,因为IEEE-754双倍-precision数字只有15位数的精度..)

  4. ... === str:将其与原始字符串进行比较。

  5. n >= 0:检查一下是否正确。

  6. 请注意,对于输入"+1",输入String(...),科学记数法中的任何输入在1234567890123456789阶段没有变回相同的科学记数法,以及任何值的数字,这都是失败的JavaScript使用(IEEE-754双精度二进制浮点)无法准确地表示哪个解析更接近于给定的一个不同的值(包括超过9,007,199,254,740,992的许多整数;例如,+将失败)。前者很容易解决,后两者不是很多。

    正则表达式

    另一种方法是通过正则表达式测试字符串的字符,如果你的目标只是允许(比方说)一个可选的0后跟function isNormalInteger(str) { return /^\+?(0|[1-9]\d*)$/.test(str); } 或正常小数的字符串格式:

    function isNormalInteger(str) {
        return /^\+?(0|[1-9]\d*)$/.test(str);
    }
    function gid(id) {
      return document.getElementById(id);
    }
    function test(str, expect) {
      console.log(str + ": " + (isNormalInteger(str) ? "Yes" : "No"));
    }
    gid("btn").addEventListener(
      "click",
      function() {
        test(gid("text").value);
      },
      false
    );
    test("1");
    test("1.23");
    test("1234567890123");
    test("1234567890123.1");

    Live testbed:

    <label>
      String:
      <input id="text" type="text" value="">
    <label>
    <input id="btn" type="button" value="Check">
    ^

    如何运作:

    1. \+?:匹配字符串的开头

    2. +:允许使用一个可选的(?:...|...)(如果您不想删除此内容)

    3. (0|...):允许以下两个选项中的一个(不创建捕获组):

      1. 0:自行允许(...|[1-9]\d*) ...

      2. 0:...或以$以外的其他内容开头的数字,后跟任意数量的小数位。

    4. 0:匹配字符串的结尾。

    5. 如果你想禁止/^\+?[1-9]\d*$/(因为它不是正面的),正则表达式只会变成0(例如,我们可能会失去允许(?:0|[1-9]\d*)所需的替换。

      如果您想允许前导零(0123,00524),则只需将替换\d+替换为function isNormalInteger(str) { return /^\+?\d+$/.test(str); }

      +str

      当您将其转换为数字时请注意:在现代引擎上,使用Number(str)parseInt(str, 10)来执行此操作可能会很好,但较旧的引擎可能会扩展为非标准引擎(但以前允许的方式表示前导零表示八进制(基数为8),例如“010”=&gt; 8.一旦验证了数字,就可以安全地使用parseInt来确保它被解析为十进制数(基数为10)。 {{1}}会忽略字符串末尾的垃圾,但我们确保没有任何正则表达式。

答案 1 :(得分:69)

解决方案1 ​​

如果我们consider JavaScript整数为最大值4294967295(即Math.pow(2,32)-1),那么以下简短解决方案将完美无缺:

function isPositiveInteger(n) {
    return n >>> 0 === parseFloat(n);
}

说明

  1. Zero-fill right shift operator做了三件重要的事情:
    • 截断小数部分
      • 123.45 >>> 0 === 123
    • 负数的变化
      • -1 >>> 0 === 4294967295
    • “工作”范围为MAX_INT
      • 1e10 >>> 0 === 1410065408
      • 1e7 >>> 0 === 10000000
  2. parseFloat确实正确解析字符串数字(为非数字字符串设置NaN
  3. <强>测试:

    "0"                     : true
    "23"                    : true
    "-10"                   : false
    "10.30"                 : false
    "-40.1"                 : false
    "string"                : false
    "1234567890"            : true
    "129000098131766699.1"  : false
    "-1e7"                  : false
    "1e7"                   : true
    "1e10"                  : false
    "1edf"                  : false
    " "                     : false
    ""                      : false
    

    DEMO: http://jsfiddle.net/5UCy4/37/


    解决方案2

    另一种方法适用于有效期最高为Number.MAX_VALUE的所有数值,即大约1.7976931348623157e+308

    function isPositiveInteger(n) {
        return 0 === n % (!isNaN(parseFloat(n)) && 0 <= ~~n);
    }
    

    说明

    1. !isNaN(parseFloat(n))用于过滤字符串值,例如""" ""string";
    2. 0 <= ~~n过滤负的和大的非整数值,例如"-40.1""129000098131766699";
    3. 如果值数字正面,则
    4. (!isNaN(parseFloat(n)) && 0 <= ~~n)会返回true;
    5. 0 === n % (...)检查值是否为非浮点数 - 此处(...)(参见3)在0的情况下评估为false,{{1}如果是1
    6. <强>测试:

      true

      DEMO: http://jsfiddle.net/5UCy4/14/


      以前的版本:

      "0"                     : true
      "23"                    : true
      "-10"                   : false
      "10.30"                 : false
      "-40.1"                 : false
      "string"                : false
      "1234567890"            : true
      "129000098131766699.1"  : false
      "-1e10"                 : false
      "1e10"                  : true
      "1edf"                  : false
      " "                     : false
      ""                      : false
      

      DEMO: http://jsfiddle.net/5UCy4/2/

答案 2 :(得分:19)

看起来像是正则表达式:

var isInt = /^\+?\d+$/.test('the string');

答案 3 :(得分:10)

The modern solution that works in node and across over 90% of all browsers (except IE and Opera Mini) is to use Number.isInteger followed by a simple positive check.

Number.isInteger(x) && x > 0

This was finalized in ECMAScript 2015.

function isPositiveInteger(x) {
    return Number.isInteger(x) && x > 0
}

The Polyfil is:

Number.isInteger = Number.isInteger || function(value) {
  return typeof value === 'number' && 
    isFinite(value) && 
    Math.floor(value) === value;
};

If you need to support input that might be in string or number form then you can use this function I wrote a large test suite against after all the existing answers (2/1/2018) failed on some form of input.

function isPositiveInteger(v) {
  var i;
  return v && (i = parseInt(v)) && i > 0 && (i === v || ''+i === v);
}

答案 4 :(得分:3)

对于这个问题,这几乎是一个重复的问题:

Validate decimal numbers in JavaScript - IsNumeric()

答案是:

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

所以,正整数将是:

function isPositiveInteger(n) {
  var floatN = parseFloat(n);
  return !isNaN(floatN) && isFinite(n) && floatN > 0
      && floatN % 1 == 0;
}

答案 5 :(得分:2)

return ((parseInt(str, 10).toString() == str) && str.indexOf('-') === -1);
如果您提供类似'0001'的字符串,

将无效

答案 6 :(得分:2)

我的函数检查数字是否为+ ve,并且也可能有十进制值。

       function validateNumeric(numValue){
            var value = parseFloat(numValue);
            if (!numValue.toString().match(/^[-]?\d*\.?\d*$/)) 
                    return false;
            else if (numValue < 0) {
                return false;
            }
            return true;        
        }

答案 7 :(得分:2)

仅仅基于VisioN上面的答案,如果你使用的是jQuery验证插件,你可以使用它:

$(document).ready(function() {
    $.validator.addMethod('integer', function(value, element, param) {
        return (value >>> 0 === parseFloat(value) && value > 0);
    }, 'Please enter a non zero integer value!');
}

然后您可以在常规规则集中使用或以这种方式动态添加它:

$("#positiveIntegerField").rules("add", {required:true, integer:true});

答案 8 :(得分:1)

(~~a == a)其中a是字符串。

答案 9 :(得分:1)

简单

function isInteger(num) {
  return (num ^ 0) === num;
}

console.log(isInteger(1));

您还可以扩展Number并通过原型为其分配功能。

答案 10 :(得分:1)

ES6:

num

答案 11 :(得分:1)

这就是我验证字符串是正整数的方式。

var str = "123";
var str1 = "1.5";
var str2 = "-123";

console.log("is str positive integer: ", Number.isInteger(Number(str)) && Number(str) > 0)
console.log("is str1 positive integer: ", Number.isInteger(Number(str1)) && Number(str1) > 0)
console.log("is str2 positive integer: ", Number.isInteger(Number(str2)) && Number(str2) > 0)

答案 12 :(得分:0)

只需使用

let num = 1.2;
let res;
res = Number.isInteger(num);
console.log(res);

您将获得正确或错误的结果。

如果为整数,则返回true,否则返回false。

答案 13 :(得分:0)

大多数时候,您需要这种类型的数据库使用检查,例如检查字符串是否有效的userId。因为没有任何奇怪的符号可以解析为整数。整数也应在整数的数据库范围内。您只需要像1,2,3这样的普通int即可。

const isStrNormPosInt = (str: string) => {
  return /^([1-9]\d*)$/.test(str) && Number(str) <= 2147483647 // postgres max int
}

如果支票通过,则可以将其转换为数字Number(str)