JS RegEx替换未捕获的组?

时间:2017-07-24 15:32:04

标签: javascript regex

我目前正在阅读“Eloquent JavaScript”一书。关于正则表达式的第9章末尾有一个exercice,我无法很好地理解它的解决方案。可以找到exercice的描述here

TL; DR:目标是在给定字符串中用双引号(“)替换单引号('),同时在收缩中保留单引号。当然使用替换方法和RegEx

现在,在使用我自己的方法实际解决此练习后,我检查了建议的解决方案,如下所示:

console.log(text.replace(/(^|\W)'|'(\W|$)/g, '$1"$2'));

RegEx看起来很好,这是可以理解的,但我不明白的是替换的使用,主要是为什么使用$2有效?据我所知,这个正则表达式只采用两个路径,(^|\W)''(\W|$)这些路径中的每一个只会产生一个捕获的组,所以我们只有{{1}可用。然而$1正在捕获单引号之后的内容而没有在正则表达式中执行此操作的显式第二个捕获组。有人可以争辩说有两组,但是再次$2捕获的字符串不同于第二组所预期的字符串。

我的问题:

  • 为什么$2实际上是一个有效的字符串而不是$2,它究竟指的是什么?
  • 这是JavaScript RegEx的怪癖吗?
  • 这是否意味着undefined并不总是引用显式组?

1 个答案:

答案 0 :(得分:1)

在每次匹配时使用空字符串初始化反向引用,因此如果组不匹配则不会出现问题。这不是怪癖,符合ES5标准。

以下是Backreferences to Failed Groups的引用:

  

根据ECMA的官方标准,对非参与捕获组的反向引用必须成功地匹配任何只捕获到没有捕获任何内容的参与组的反向引用。

因此,一旦反向引用没有参与匹配,它就会引用一个空字符串,而不是未定义。它不是一个怪癖,只是一个“功能”。这有点不太令人期待,但它只是它的运作方式。

在您的方案中,任何一个后向引用在匹配时都是空的,因为有两个备用分支,每次只有一个匹配。重点是恢复任一组中匹配的字符。两个反向引用都用作其中任何一个包含要还原的文本而另一个只包含空文本。