Javascript 验证字符串是否为正整数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10834796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:07:53  来源:igfitidea点击:

Validate that a string is a positive integer

javascript

提问by Mick Byrne

I would like the simplest fail-safe test to check that a string in JavaScript is a positive integer.

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

isNaN(str)returns true for all sorts of non-integer values and parseInt(str)is returning integers for float strings, like "2.5". And I don't want to have to use some jQuery plugin either.

isNaN(str)为各种非整数值返回 true,并parseInt(str)为浮点字符串返回整数,如“2.5”。而且我也不想使用一些 jQuery 插件。

回答by T.J. Crowder

Two answers for you:

给你两个答案:

  • Based on parsing

  • Regular expression

  • 基于解析

  • 正则表达式

Note that in both cases, I've interpreted "positive integer" to include 0, even though 0is not positive. I include notes if you want to disallow 0.

请注意,在这两种情况下,我都将“正整数”解释为 include 0,即使0不是正数。如果您想禁止0.

Based on Parsing

基于解析

If you want it to be a normalized decimal integer string over a reasonable range of values, you can do this:

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

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

or if you want to allow whitespace and leading zeros:

或者如果你想允许空格和前导零:

function isNormalInteger(str) {
    str = str.trim();
    if (!str) {
        return false;
    }
    str = str.replace(/^0+/, "") || "0";
    var n = Math.floor(Number(str));
    return n !== Infinity && String(n) === str && n >= 0;
}

Live testbed (without handling leading zeros or whitespace):

实时测试台(不处理前导零或空格):

function isNormalInteger(str) {
    var n = Math.floor(Number(str));
    return n !== Infinity && String(n) === str && n >= 0;
}
function gid(id) {
    return document.getElementById(id);
}
function test(str, expect) {
    var result = isNormalInteger(str);
    console.log(
        str + ": " +
        (result ? "Yes" : "No") +
        (expect === undefined ? "" : !!expect === !!result ? " <= OK" : " <= ERROR ***")
    );
}
gid("btn").addEventListener(
    "click",
    function() {
        test(gid("text").value);
    },
    false
);
test("1", true);
test("1.23", false);
test("1234567890123", true);
test("1234567890123.1", false);
test("0123", false); // false because we don't handle leading 0s
test(" 123 ", false); // false because we don't handle whitespace
<label>
  String:
  <input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">

Live testbed (withhandling for leading zeros and whitespace):

现场测试平台(处理的前导零和空格):

function isNormalInteger(str) {
    str = str.trim();
    if (!str) {
        return false;
    }
    str = str.replace(/^0+/, "") || "0";
    var n = Math.floor(Number(str));
    return String(n) === str && n >= 0;
}
function gid(id) {
    return document.getElementById(id);
}
function test(str, expect) {
    var result = isNormalInteger(str);
    console.log(
        str + ": " +
        (result ? "Yes" : "No") +
        (expect === undefined ? "" : !!expect === !!result ? " <= OK" : " <= ERROR ***")
    );
}
gid("btn").addEventListener(
    "click",
    function() {
        test(gid("text").value);
    },
    false
);
test("1", true);
test("1.23", false);
test("1234567890123", true);
test("1234567890123.1", false);
test("0123", true);
test(" 123 ", true);
<label>
  String:
  <input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">

If you want to disallow 0, just change >= 0to > 0. (Or, in the version that allows leading zeros, remove the || "0"on the replaceline.)

如果您想禁止0,只需更改>= 0> 0. (或者,在允许前导零的版本中,删除行|| "0"上的replace。)

How that works:

它是如何工作的:

  1. In the version allowing whitespace and leading zeros:

    • str = str.trim();removes any leading and trailing whitepace.
    • if (!str)catches a blank string and returns, no point in doing the rest of the work.
    • str = str.replace(/^0+/, "") || "0";removes all leading 0s from the string — but if that results in a blank string, restores a single 0.
  2. Number(str): Convert strto a number; the number may well have a fractional portion, or may be NaN.

  3. Math.floor: Truncate the number (chops off any fractional portion).

  4. String(...): Converts the result back into a normal decimal string. For really big numbers, this will go to scientific notation, which may break this approach. (I don't quite know where the split is, the details are in the spec, but for whole numbers I believe it's at the point you've exceeded 21 digits [by which time the number has become very imprecise, as IEEE-754 double-precision numbers only have roughtly 15 digits of precision..)

  5. ... === str: Compares that to the original string.

  6. n >= 0: Check that it's positive.

  1. 在允许空格和前导零的版本中:

    • str = str.trim();删除任何前导和尾随空格。
    • if (!str)捕获一个空白字符串并返回,做其余的工作毫无意义。
    • str = str.replace(/^0+/, "") || "0";从字符串中删除所有前导 0——但如果这导致一个空字符串,则恢复单个 0。
  2. Number(str): 转换str为数字;该数字可能有一个小数部分,或者可能是NaN

  3. Math.floor:截断数字(切掉任何小数部分)。

  4. String(...): 将结果转换回普通的十进制字符串。对于非常大的数字,这将采用科学记数法,这可能会破坏这种方法。(我不太清楚拆分在哪里,详细信息在规范中,但是对于整数,我相信您已经超过了 21 位 [到那时数字变得非常不精确,如 IEEE-754双精度数字只有大约 15 位精度..)

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

  6. n >= 0: 检查是阳性。

Note that this fails for the input "+1", any input in scientific notation that doesn't turn back into the same scientific notation at the String(...)stage, and for any value that the kind of number JavaScript uses (IEEE-754 double-precision binary floating point) can't accurately represent which parses as closer to a different value than the given one (which includes many integers over 9,007,199,254,740,992; for instance, 1234567890123456789will fail). The former is an easy fix, the latter two not so much.

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

Regular Expression

正则表达式

The other approach is to test the characters of the string via a regular expression, if your goal is to just allow (say) an optional +followed by either 0or a string in normal decimal format:

另一种方法是通过正则表达式测试字符串的字符,如果您的目标是只允许(比如说)一个可选的,+后跟一个0或一个普通十进制格式的字符串:

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

Live testbed:

现场试验台:

function isNormalInteger(str) {
    return /^\+?(0|[1-9]\d*)$/.test(str);
}
function gid(id) {
    return document.getElementById(id);
}
function test(str, expect) {
    var result = isNormalInteger(str);
    console.log(
        str + ": " +
        (result ? "Yes" : "No") +
        (expect === undefined ? "" : !!expect === !!result ? " <= OK" : " <= ERROR ***")
    );
}
gid("btn").addEventListener(
    "click",
    function() {
        test(gid("text").value);
    },
    false
);
test("1", true);
test("1.23", false);
test("1234567890123", true);
test("1234567890123.1", false);
test("0123", false); // false because we don't handle leading 0s
test(" 123 ", false); // false because we don't handle whitespace
<label>
  String:
  <input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">

How that works:

它是如何工作的:

  1. ^: Match start of string

  2. \+?: Allow a single, optional +(remove this if you don't want to)

  3. (?:...|...): Allow one of these two options (without creating a capture group):

    1. (0|...): Allow 0on its own...

    2. (...|[1-9]\d*): ...or a number starting with something other than 0and followed by any number of decimal digits.

  4. $: Match end of string.

  1. ^: 匹配字符串的开头

  2. \+?: 允许一个,可选的+(如果你不想删除这个)

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

    1. (0|...): 允许0自己...

    2. (...|[1-9]\d*): ... 或以其他数字开头0并后跟任意数量的十进制数字的数字。

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

If you want to disallow 0(because it's not positive), the regular expression becomes just /^\+?[1-9]\d*$/(e.g., we can lose the alternation that we needed to allow 0).

如果你想禁止0(因为它不是正数),正则表达式就会变成 just /^\+?[1-9]\d*$/(例如,我们可能会失去我们需要允许的交替0)。

If you want to allow leading zeroes (0123, 00524), then just replace the alternation (?:0|[1-9]\d*)with \d+

如果您想允许前导零 (0123, 00524),则只需将交替替换(?:0|[1-9]\d*)\d+

function isNormalInteger(str) {
    return /^\+?\d+$/.test(str);
}

If you want to allow whitespace, add \s*just after ^and \s*just before $.

如果要允许空格,请\s*在 之后^\s*之前添加$

Note for when you convert that to a number: On modern engines it would probably be fine to use +stror Number(str)to do it, but older ones might extend those in a non-standard (but formerly-allowed) way that says a leading zero means octal(base 8), e.g "010" => 8. Once you've validated the number, you can safely use parseInt(str, 10)to ensure that it's parsed as decimal (base 10). parseIntwould ignore garbage at the end of the string, but we've ensured there isn't any with the regex.

将其转换为数字时的注意事项:在现代引擎上使用+strNumber(str)执行它可能没问题,但较旧的引擎可能会以非标准(但以前允许)的方式扩展它们,即前导零表示八进制(基数 8),例如“010”=> 8。一旦您验证了数字,您就可以安全地使用parseInt(str, 10)它来确保它被解析为十进制(基数 10)。parseInt会忽略字符串末尾的垃圾,但我们确保正则表达式中没有垃圾。

回答by VisioN

Solution 1

解决方案1

If we considera JavaScript integer to be a value of maximum 4294967295(i.e. Math.pow(2,32)-1), then the following short solution will perfectly work:

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

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

DESCRIPTION:

描述:

  1. Zero-fill right shift operatordoes three important things:
    • truncates decimal part
      • 123.45 >>> 0 === 123
    • does the shift for negative numbers
      • -1 >>> 0 === 4294967295
    • "works" in range of MAX_INT
      • 1e10 >>> 0 === 1410065408
      • 1e7 >>> 0 === 10000000
  2. parseFloatdoes correct parsing of string numbers (setting NaNfor non numeric strings)
  1. 零填充右移运算符做了三件重要的事情:
    • 截断小数部分
      • 123.45 >>> 0 === 123
    • 负数的移位
      • -1 >>> 0 === 4294967295
    • 范围内的“作品” MAX_INT
      • 1e10 >>> 0 === 1410065408
      • 1e7 >>> 0 === 10000000
  2. parseFloat正确解析字符串数字(NaN非数字字符串的设置)

TESTS:

测试:

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

演示:http : //jsfiddle.net/5UCy4/37/



Solution 2

解决方案2

Another way is good for all numeric values which are valid up to Number.MAX_VALUE, i.e. to about 1.7976931348623157e+308:

另一种方法适用于有效至Number.MAX_VALUE,即至 about 的所有数值1.7976931348623157e+308

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

DESCRIPTION:

描述:

  1. !isNaN(parseFloat(n))is used to filter purestring values, e.g. "", " ", "string";
  2. 0 <= ~~nfilters negative and large non-integer values, e.g. "-40.1", "129000098131766699";
  3. (!isNaN(parseFloat(n)) && 0 <= ~~n)returns trueif value is both numericand positive;
  4. 0 === n % (...)checks if value is non-float -- here (...)(see 3) is evaluated as 0in case of false, and as 1in case of true.
  1. !isNaN(parseFloat(n))用于过滤字符串值,例如"", " ", "string";
  2. 0 <= ~~n过滤负值和大的非整数值,例如"-40.1""129000098131766699"
  3. (!isNaN(parseFloat(n)) && 0 <= ~~n)true如果 value 既是数字又是,则返回;
  4. 0 === n % (...)检查,如果值不浮-在这里(...)(参见图3)被评价为0在以下情况下false,并且如1在以下情况下true

TESTS:

测试:

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

演示:http : //jsfiddle.net/5UCy4/14/



The previous version:

之前的版本:

function isPositiveInteger(n) {
    return n == "0" || ((n | 0) > 0 && n % 1 == 0);
}

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

演示:http : //jsfiddle.net/5UCy4/2/

回答by Niko

Looks like a regular expression is the way to go:

看起来正则表达式是要走的路:

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

回答by Xeoncross

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

适用于 node 和超过 90% 的所有浏览器(IE 和 Opera Mini 除外)的现代解决方案是使用Number.isInteger,然后进行简单的肯定检查。

Number.isInteger(x) && x > 0

This was finalized in ECMAScript 2015.

在 ECMAScript 2015完成

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

The Polyfil is:

Polyfil 是:

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 stringor numberform then you can use this function I wrote a large test suite againstafter all the existing answers (2/1/2018) failed on some form of input.

如果您需要支持可能是字符串数字形式的输入,那么您可以使用此函数,在所有现有答案 (2/1/2018) 在某种形式的输入上失败后,我编写了一个大型测试套件

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

回答by Chango

This is almost a duplicate question fo this one:

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

Validate decimal numbers in JavaScript - IsNumeric()

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

It's answer is:

它的答案是:

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

so, a positive integer would be:

所以,一个正整数将是:

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

回答by manish kumar

Simple

简单的

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

console.log(isInteger(1));

You can also extend Number and assign the function to it via prototype.

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

回答by Sebas

return ((parseInt(str, 10).toString() == str) && str.indexOf('-') === -1);

won't work if you give a string like '0001' though

如果你给一个像 '0001' 这样的字符串就行不通

回答by Deepak Nirala

My function checks if number is +ve and could be have decimal value as well.

我的函数检查 number 是否为 +ve 并且也可以具有十进制值。

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

回答by usr-bin-drinking

Just to build on VisioN's answer above, if you are using the jQuery validation plugin you could use this:

只是为了建立在上面 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!');
}

Then you could use in your normal rules set or add it dynamically this way:

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

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

回答by mggluscevic

If you are using HTML5 forms, you can use attribute min="0"for form element <input type="number" />. This is supported by all major browsers. It does not involve Javascript for such simple tasks, but is integrated in new html standard. It is documented on https://www.w3schools.com/tags/att_input_min.asp

如果您使用 HTML5 表单,您可以使用min="0"表单元素的属性<input type="number" />。所有主要浏览器都支持这一点。它不涉及用于此类简单任务的 Javascript,但已集成到新的 html 标准中。它记录在https://www.w3schools.com/tags/att_input_min.asp