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

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


当前回答

我的问题基本上是相同的:检查用户输入的数字是否为整数和正数。

我们的朋友Levi的代码和响应是我迄今为止在整个互联网上发现的最好的,在处理错误方面令人满意。

我在网站(https://bobbyhadz.com/blog/javascript-check-if-string-is-positive-integer):)上找到了下面的代码

function isPositiveInteger(str) {
   if (typeof str !== 'string') {
     return false;
   }
   const num = Number(str);
   if (Number.isInteger(num) && num > 0) {
     return true;
   }
   return false;
}

但是,对于1e10,它不能正确返回。

其他回答

如果你正在使用HTML5表单,你可以使用attribute min="0" for form element <input type="number" />。所有主流浏览器都支持这一功能。它不需要Javascript来完成这些简单的任务,而是集成在新的html标准中。 它被记录在https://www.w3schools.com/tags/att_input_min.asp上

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

但是,如果您提供'0001'这样的字符串,则无法工作

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

我的问题基本上是相同的:检查用户输入的数字是否为整数和正数。

我们的朋友Levi的代码和响应是我迄今为止在整个互联网上发现的最好的,在处理错误方面令人满意。

我在网站(https://bobbyhadz.com/blog/javascript-check-if-string-is-positive-integer):)上找到了下面的代码

function isPositiveInteger(str) {
   if (typeof str !== 'string') {
     return false;
   }
   const num = Number(str);
   if (Number.isInteger(num) && num > 0) {
     return true;
   }
   return false;
}

但是,对于1e10,它不能正确返回。

给你两个答案:

基于解析 正则表达式

注意,在这两种情况下,我都将“正整数”解释为包括0,尽管0不是正的。如果你不允许0,我就包括注释。

基于解析

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

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

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

function isInDesiredForm(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;
}

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

function isInDesiredForm(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 = isInDesiredForm(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">

实时测试平台(处理前导零和空白):

function isInDesiredForm(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 = isInDesiredForm(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">

如果不允许0,只需将>= 0更改为> 0。(或者,在允许前导零的版本中,删除替换行上的||“0”。)

如何运作:

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

STR = STR .trim();删除任何前导和尾随空格。 如果(!str)捕获一个空字符串并返回,则没有必要执行其余工作。 STR = STR .replace(/^0+/, "") || "0";从字符串中删除所有前导0 -但如果结果为空字符串,则恢复单个0。

Number(str): Convert str to a number; the number may well have a fractional portion, or may be NaN. Math.floor: Truncate the number (chops off any fractional portion). 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..) ... === str: Compares that to the original string. n >= 0: Check that it's positive.

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, 1234567890123456789 will fail). The former is an easy fix, the latter two not so much.

正则表达式

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

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

生活的实验:

function isInDesiredForm(str) { return /^\+?(0|[1-9]\d*)$/.test(str); } function gid(id) { return document.getElementById(id); } function test(str, expect) { var result = isInDesiredForm(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">

如何运作:

^:匹配字符串的开始 \ + ?:允许一个单独的,可选的+(如果你不想删除这个) (?:…|…):允许以下两个选项之一(不创建捕获组): (0|…):允许0自己… (…| (1 - 9)\ d *):……或者以非0的数字开头,后面跟着任意位数的十进制数字。 $:匹配字符串结束。

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

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

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

如果你想允许空格,在^后面加上\s*,在$之前加上\s*。

注意,当你把它转换成一个数字:在现代引擎上,使用+str或number (str)可能会很好,但旧的引擎可能会以一种非标准(但以前允许的)方式扩展它们,表示前导零意味着八进制(以8为基数),例如“010”=> 8。验证完数字后,可以安全地使用parseInt(str, 10)来确保它被解析为十进制(以10为基数)。parseInt将忽略字符串末尾的垃圾,但我们已经确保正则表达式中没有任何垃圾。