验证字符串是否为正整数

Mic*_*rne 192 javascript

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

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

T.J*_*der 284

两个答案:

  • 基于解析

  • 正则表达式

请注意,在这两种情况下,我都将"正整数"解释为包括在内0,即使0它不是正数.如果你想禁止,我会加注0.

基于解析

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

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

现场试验台:

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;
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

如果你想禁止0,只需>= 0改为> 0.

工作原理:

  1. || "0":转换replace为数字; 该数字可能具有小数部分,或者可能是str = str.trim();.

  2. if (!str):截断数字(截断任何小数部分).

  3. str = str.replace(/^0+/, "") || "0";:将结果转换回正常的十进制字符串.对于非常大的数字,这将采用科学记数法,这可能会破坏这种方法.(我不太清楚分割的位置,细节在规格中,但对于整数,我相信它已超过21位数[此时数字变得非常不精确,因为IEEE-754双精度数字只有15位数的精度..)

  4. Number(str):将其与原始字符串进行比较.

  5. str:检查一下是否正面.

请注意,输入失败NaN,科学记数法中的任何输入都不会在Math.floor阶段返回到相同的科学记数法,以及JavaScript使用的任何数值(IEEE-754双精度二进制浮点数)无法准确地表示哪个解析更接近于与给定值不同的值(其中包括超过9,007,199,254,740,992的许多整数;例如,String(...)将失败).前者是一个简单的解决方案,后两个并不是那么多.

正则表达式

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

<label>
  String:
  <input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">
Run Code Online (Sandbox Code Playgroud)

现场试验台:

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);
Run Code Online (Sandbox Code Playgroud)
<label>
  String:
  <input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">
Run Code Online (Sandbox Code Playgroud)

工作原理:

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

  2. String(...):允许单个,可选1234567890123456789(如果你不想删除它)

  3. +:允许这两个选项之一(不创建捕获组):

    1. 0:允许^自己......

    2. \+?:...或以除了+后跟任意数量的十进制数字开头的数字.

  4. (?:...|...):匹配字符串的结尾.

如果你想禁止(0|...)(因为它不是正面的),正则表达式就变得正常0(例如,我们可能会失去我们需要允许的交替(...|[1-9]\d*)).

如果你想允许前导零(0123,00524),则只需更换交替0使用$

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

注意当你将它转换为数字时:在现代引擎上使用0/^\+?[1-9]\d*$/执行它可能没什么问题,但是较旧的引擎可能会以非标准(但以前允许)的方式扩展它们,即前导零表示八进制(基数8),例如"010"=> 8.一旦验证了数字,就可以安全地使用0它来确保它被解析为十进制(基数为10).(?:0|[1-9]\d*)会忽略字符串末尾的垃圾,但我们已经确保没有任何正则表达式.


Vis*_*ioN 72

解决方案1

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

function isPositiveInteger(n) {
    return n >>> 0 === parseFloat(n);
}
Run Code Online (Sandbox Code Playgroud)

描述:

  1. 零填充右移运算符有三个重要的事情:
    • 截断小数部分
      • 123.45 >>> 0 === 123
    • 负数的变化
      • -1 >>> 0 === 4294967295
    • "工作"在范围内 MAX_INT
      • 1e10 >>> 0 === 1410065408
      • 1e7 >>> 0 === 10000000
  2. 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
Run Code Online (Sandbox Code Playgroud)

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


解决方案2

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

function isPositiveInteger(n) {
    return 0 === n % (!isNaN(parseFloat(n)) && 0 <= ~~n);
}
Run Code Online (Sandbox Code Playgroud)

描述:

  1. !isNaN(parseFloat(n))用于过滤字符串值,例如""," ","string";
  2. 0 <= ~~n过滤器负和大的非整数值,例如"-40.1","129000098131766699";
  3. (!isNaN(parseFloat(n)) && 0 <= ~~n)true如果值既是数字又是,则返回;
  4. 0 === n % (...)检查,如果值不浮-在这里(...)(参见图3)被评价为0在以下情况下false,并且如1在以下情况下true.

测试:

"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
Run Code Online (Sandbox Code Playgroud)

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


以前的版本:

function isPositiveInteger(n) {
    return n == "0" || ((n | 0) > 0 && n % 1 == 0);
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Niko答案已经更新,现在有效;) (2认同)

Nik*_*iko 20

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

var isInt = /^\+?\d+$/.test('the string');
Run Code Online (Sandbox Code Playgroud)


Xeo*_*oss 12

在节点和超过90%的浏览器(IE和Opera Mini除外)中运行的现代解决方案是使用Number.isInteger,然后进行简单的正检查.

Number.isInteger(x) && x > 0
Run Code Online (Sandbox Code Playgroud)

这是在ECMAScript 2015最终确定的.

function isPositiveInteger(x) {
    return Number.isInteger(x) && x > 0
}
Run Code Online (Sandbox Code Playgroud)

Polyfil是:

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

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

function isPositiveInteger(v) {
  var i;
  return v && (i = parseInt(v)) && i > 0 && (i === v || ''+i === v);
}
Run Code Online (Sandbox Code Playgroud)

  • 该问题具体询问如何测试 *string* 是否为正整数。 (2认同)

oma*_*oma 6

ES6:

Number.isInteger(Number(theNumberString)) && Number(theNumberString) > 0
Run Code Online (Sandbox Code Playgroud)


Md.*_*lah 6

这就是我验证字符串是否为正整数的方法。

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)
Run Code Online (Sandbox Code Playgroud)


Cha*_*ngo 5

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

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

它的答案是:

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}
Run Code Online (Sandbox Code Playgroud)

所以,一个正整数是:

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