0%
正则匹配中的 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>
在输入框中填写手机号,可以正常校验,而且校验结果没错。但是用鼠标选中其中一个数字,直接修改为其他数字,此时输入没问题,但校验会失败。
原因
正则表达式使用全局匹配 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)
}
问题就出在,如果匹配成功后,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'
}
}