请注意,这不是正则表达式本身的问题,而是我检测到的一些奇怪行为。 我正在使用javascript正则表达式遇到一些棘手的行为。如果我分别评估每个代码步骤,它会按预期工作,因此我认为我可能会在正则表达式中引发某种状态问题。
第一个问题是我无法直接访问正则表达式执行结果的索引。例如
const regex = /a(bc)/gm;
regex.test('abc') && regex.exec('abc')[1] // => can not acces 1 of null
我尝试将结果保存到变量中,然后尝试有条件地访问该值,但是然后我总是会出错
const doRegex = str => {
const regexRes = randomRegex.exec(str);
return randomRegex.test(str) ? regexRes[1] : str
}
console.log(doRegex('abc')) // => prints abc instead of bc
很难找到该问题的好标题,因此欢迎提出任何更新建议。
答案 0 :(得分:0)
问题出在正则表达式的全局g
标志上。
添加该标志会使正则表达式变为全局,并使正则表达式保持状态。因此,第一次执行正则表达式(无论是通过执行.test
还是通过执行.exec
都无关紧要),您正在初始化正则表达式状态。第一次执行正则表达式时,您会在.test
情况下为true或在.exec
情况下为正确的匹配。下次您再次执行正则表达式时,它将“提前”它的状态,尝试匹配下一个结果。由于您的字符串仅匹配一次,因此结果将为null,正则表达式将重置其状态。
您的选择是,删除全局标志或在函数体内声明正则表达式(以避免状态保留),然后仅执行一次。
const doRegex = str => {
const regexRes = (/a(bc)/gm).exec(str);
return regexRes ? regexRes[1] : str
}
该代码仅执行一次正则表达式,并且每次执行该函数时都会创建一个新的正则表达式对象,因此,如果在函数外声明正则表达式,则不会出现状态保留问题。
编辑: @LGSon评论说,您还可以将所需的参数传递给不同的regex函数:
如果将标志作为参数传递给regex函数,它将 工作。例如。
randomRegex.exec(str, /gm/);
...randomRegex.test(str,/gm/)