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

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


看起来正则表达式是可行的:

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

给你两个答案:

基于解析 正则表达式

注意,在这两种情况下,我都将“正整数”解释为包括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将忽略字符串末尾的垃圾,但我们已经确保正则表达式中没有任何垃圾。


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

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


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

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

解决方案1

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

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

描述:

零填充右移操作符有三件重要的事情: 截断小数部分 123.45 >>> 0 === 123 对负数有移位吗 -1 >>> 0 === 4294967295 MAX_INT范围内的"works" 1e10 >>> 0 === 1410065408 1e7 >>> 0 === 10000000 parseFloat正确解析字符串数字(为非数字字符串设置NaN)

测试:

"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

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


解决方案2

另一种方法适用于在Number之前有效的所有数值。MAX_VALUE,即约1.7976931348623157e+308:

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

描述:

isNaN(parseFloat(n))用于过滤纯字符串值,例如:"", "", "string"; 0 <= ~~n过滤负的和大的非整数值,例如:“-40.1”,“129000098131766699”; (!isNaN(parseFloat(n)) && 0 <= ~~n)如果value为数值且为正数则返回true; 0 === n %(…)检查value是否为非浮点值——这里(…)(见3)在false的情况下被计算为0,在true的情况下被计算为1。

测试:

"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

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


以前的版本:

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

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


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


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

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

根据上面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});

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


适用于node和90%以上浏览器(IE和Opera Mini除外)的现代解决方案是使用Number。isInteger后跟一个简单的正检查。

Number.isInteger(x) && x > 0

这是在ECMAScript 2015中完成的。

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

Polyfil是:

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

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

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

简单的

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

console.log(isInteger(1));

你也可以扩展Number并通过prototype将函数赋值给它。


ES6:

Number.isInteger(Number(theNumberString)) && Number(theNumberString) > 0

这就是我如何验证一个字符串是一个正整数。

瓦尔str =“123”; var str1 =“1.5”; var str2 = -123; 控制台(“is str positive integer:”,数字.isInteger(数字(str)和数字(str) > 0) 控制台(“is str1正图:”,数字.isInteger(数字(str1)和数字(str1) > 0) 控制台(“is str2正图:”,isInteger(数字(str2): && Number(str2) > 0)


大多数情况下,您需要这种类型的数据库使用检查,如检查字符串是否有效的userId。正因为如此,不可能有任何奇怪的符号可以被分割成整数。此外,整数应该在数据库的整数范围内。你只需要普通的整数,比如1 2 3等等。

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

如果检查通过了,你可以把它转换成number number (str)


我的标准需要在@VisioN的答案上进行一些额外的检查。

不是负数,包括-0 不是小数部分为零的浮点数——0.0,1.000000 不是指数形式的数字,1e10

我发现这对于验证Express路由器的路由参数很有用。例如/书/:bookId

Code

/**
 * Validate that a string is a positive integer
 * Excludes float numbers with a zero decimal part, exponential notation and negative 0
 * @param n
 * @returns {boolean}
 */
function isStrictlyPositiveInteger(n) {
    const nString = n.toString(), nInt = parseInt(n), nFloat = parseFloat(n);
    // if a negative number (works on -0)
    if (nString.charAt(0) === '-') {
        return false;
    }
    // if an exponential like 1e10
    if (nString.indexOf('e') > -1) {
        return false;
    }
    // if a float number with a zero decimal part e.g 0.0
    if ((nFloat === nInt) && (nString.indexOf('.') > -1)) {
        return false;
    }
    // if a positive integer
    // https://stackoverflow.com/a/10835227/8470877
    return (0 === n % (!isNaN(nFloat) && 0 <= ~~n));
}

测试

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

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

我们的朋友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,它不能正确返回。