JavaScript 中正则匹配时结果不一致的问题

考察如下场景,我们有个输入框组件,输入时同时进行校验。

interface IInputProps {
label: string;
}

function Input({ label }: IInputProps) {
const [err, setErr] = useState<string | undefined>();

return (


{label}:
<input
type=“text”
onChange={(event) => {
setErr(rulePassword(event.currentTarget.value));
}}
/>

validate result:{err}



);
}

进行校验的逻辑使用了正则来测试:

const passwrodReg = new RegExp(
// eslint-disable-next-line no-useless-escape
/(?!(\d+|[a-zA-Z]+|[_+-=!@#$%^*()]+)$)[\w_+-=!@#$%^*()]{8,64}$/,
“gm”
);

export const rulePassword = (value: string) => {
const result = passwrodReg.test(value);
console.log(input:${value} result:${result});
return result ? “✅” : “❌”;
};

通常,如果是密码输入框,很自然地我们会放置两个这样的输入框以让用户确保密码的一致性:

function App() {
return (





);
}

对于相同的输入正则测试结果出现偏差
到此,示例写完了,运行后发现个诡谲的问题,如下图 GIF 中所展示:

validate resut

当我们在第一个输入框输入合法值时,显示校验结果为通过,这符合预期
当我们在第二个输入框输入相同的合法值时,居然显示校验未通过
进一步,当删除后再次输入时,又展示校验通过
同时,从控制台打印的日志也可重现上面的现象:

input:test123123 result:true
input:test123123 result:false
input: result:false
input:test123123 result:true

即,对于同样的输入 test123123,正则测试的结果居然会有偏差。

修正
当我们对校验部分的逻辑做如下变更后这个问题得以解决。

  • const passwrodReg = new RegExp(
  • // eslint-disable-next-line no-useless-escape
  • /(?!(\d+|[a-zA-Z]+|[_+-=!@#$%^*()]+)$)[\w_+-=!@#$%^*()]{8,64}$/,
  • “gm”
  • );

export const rulePassword = (value: string) => {

  • const passwrodReg = new RegExp(
  • // eslint-disable-next-line no-useless-escape
  • /(?!(\d+|[a-zA-Z]+|[_+-=!@#$%^*()]+)$)[\w_+-=!@#$%^*()]{8,64}$/,
  • “gm”
  • );
    const result = passwrodReg.test(value);
    console.log(input:${value} result:${result});
    return result ? “✅” : “❌”;
    };


validate resut

所以,一定是 RegExp 缓存了什么东西,上一次的匹配结果影响了下一次。

原因
通过查看 MDN 文档发现,RegExp 通过 test() 匹配成功时,会记录当前的位置信息然后存储到 RegExp 的 lastIndex,每成功匹配一次则更新一次该字段。

并且,

Note: As long as test() returns true, lastIndex will not reset—even when testing a different string!

当配合 g 进行全局匹配时,lastIndex 是不会重置的,即使是在匹配一个全新的字符串时。

这就解释了为什么对于相同的输入,第一次匹配成功后,后面则失败了。

而当我们每次匹配都重新调用 RegExp 构造器生成正则时,就不会有这个问题了。

还有种解决方式是去掉 g 标识,每次匹配也不会复用之前的 lastIndex。
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值