Skip to content

正则匹配中的 lastIndex 问题

复现

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>正则 bug</title>
    <style>
        #msg { color: red; display: none; }
    </style>
</head>
<body>
    <div>请输入手机号</div>
    <input id="input" type="text">
    <div id="msg">正则匹配错误</div>

    <script>
        const reg = /^1\d{10}$/g
        const msg = document.getElementById('msg')
        const input = document.getElementById('input')

        input.oninput = function () {
            if (reg.test(this.value)) {
                msg.style.display = 'none'
            } else {
                msg.style.display = 'block'
            }
        }
    </script>
</body>
</html>

在输入框中填写手机号,可以正常校验,而且校验结果没错。但是用鼠标选中其中一个数字,直接修改为其他数字,此时输入没问题,但校验会失败。

alt text

alt text

原因

正则表达式使用全局匹配 g 或者 粘性匹配 y 时,会有一个 lastIndex 属性,表示匹配到了哪个位置。

匹配不上的时候返回 0,匹配上的时候返回对应位置。

修改代码,查看 lastIndex 的值。

javascript
input.oninput = function () {
    if (reg.test(this.value)) {
        msg.style.display = 'none'
    } else {
        msg.style.display = 'block'
    }
    console.log('reg.lastIndex', reg.lastIndex)  
}

alt text

问题就出在,如果匹配成功后,lastIndex 就留在了匹配成功的位置。此时如果修改中间的数字,正则表达式也是从最后一位开始匹配。这时匹配就失败了。

解决方法

不用全局匹配

javascript
const reg = /^1\d{10}$/g
const reg = /^1\d{10}$/         // [!code ]

手动处理 lastIndex

javascript
input.oninput = function () {
    if (reg.test(this.value)) {
        msg.style.display = 'none'
        reg.lastIndex = 0
    } else {
        msg.style.display = 'block'
    }
}
评论区
评论区空空如也
发送评论
名字
0 / 20
邮箱
0 / 100
评论内容
0 / 140
由于是非实名评论,所以不提供删除功能。如果你需要删除你发送的评论,或者是其他人的评论对你造成了困扰,请 发邮件给我 。同时评论区会使用 AI + 人工的方式进行审核,以达到合规要求。

© thebestxt.cc
辽ICP备16009524号-8
本站所有文章版权所有,转载请注明出处