正则表达式匹配,但返回null

时间:2018-12-26 13:15:47

标签: javascript

请注意,这不是正则表达式本身的问题,而是我检测到的一些奇怪行为。 我正在使用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

很难找到该问题的好标题,因此欢迎提出任何更新建议。

1 个答案:

答案 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/)