小编典典

验证字符串是否为正整数

all

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

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


阅读 82

收藏
2022-05-31

共1个答案

小编典典

给你两个答案:

  • 基于解析

  • 正则表达式

请注意,在这两种情况下,我都将“正整数”解释为 include 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"replace行了。)

这是如何工作的:

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

  2. str = str.trim();删除任何前导和尾随空白。

  3. if (!str)捕获一个空白字符串并返回,其余的工作没有意义。
  4. str = str.replace(/^0+/, "") || "0";从字符串中删除所有前导 0,但如果导致空白字符串,则恢复单个 0。

  5. Number(str):转换str为数字;这个数字很可能有一个小数部分,或者可能是NaN

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

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

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

  9. n >= 0: 看看是不是阳性。

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

正则表达式

另一种方法是通过正则表达式测试字符串的字符,如果您的目标是只允许(比如说)一个可选+的,后跟一个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">

这是如何工作的:

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

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

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

  4. (0|...): 允许0自己…

  5. (...|[1-9]\d*): …或一个以非数字开头0并后跟任意数量的十进制数字的数字。

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

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

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

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

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

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

2022-05-31