我目前正在阅读“Eloquent JavaScript”一书。有一个 exercice在关于正则表达式的第 9 章末尾,我无法很好地理解它的解决方案。可以找到练习的描述 here .
TL;DR : 目标是将给定字符串中的单引号 (') 替换为双引号 ("),同时保持单引号的缩写。当然,使用带有 RegEx 的替换方法.
现在,在使用我自己的方法实际解决此练习后,我检查了建议的解决方案,如下所示:
console.log(text.replace(/(^|\W)'|'(\W|$)/g, '$1"$2'));
RegEx 看起来很好而且很容易理解,但我不明白的是替换的用法,主要是为什么使用 $2
有效?据我所知,这个正则表达式只会采用两条路径中的一条,(^|\W)'
或 '(\W|$)
这些路径中的每一条只会产生一个捕获组,所以我们只有 $1
可用。然而 $2
正在捕获单引号后面的内容,而没有在正则表达式中执行此操作的显式第二个捕获组。有人可能会争辩说有两组,但 $2
再次捕获了与第二组预期的字符串不同的字符串。
我的问题:
- 为什么
$2
实际上是一个有效的字符串而不是undefined
,它具体指的是什么? - 这是 JavaScript RegEx 怪癖之一吗?
- 这是否意味着
$1, $2...
并不总是指代明确的组?
最佳答案
反向引用在每次匹配时都用空字符串初始化,因此如果组不匹配也不会有问题。而且这不是怪癖,它符合 ES5 标准。
这是来自 Backreferences to Failed Groups 的引述:
According to the official ECMA standard, a backreference to a non-participating capturing group must successfully match nothing just a backreference to a participating group that captured nothing does.
因此,一旦反向引用不参与匹配,它就指向一个空字符串,而不是未定义的。这不是一个怪癖,只是一个“功能”。有时这并不完全符合预期,但这就是它的工作原理。
在您的场景中,任何一个反向引用在匹配时都是空的,因为有两个替代分支并且每次只有一个匹配。重点是恢复在任一组中匹配的字符。两个反向引用都被使用,因为它们中的一个包含要恢复的文本,而另一个仅包含空文本。
关于javascript - JS RegEx 替换非捕获组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45284606/