2017-07-24 105 views
1

我目前正在瀏覽「Eloquent JavaScript」一書。正則表達式的第9章末尾有一個exercice,我無法很好地理解它的解決方案。練習描述可以在here找到。JS RegEx替換未捕獲的組?

TL; DR:的目的是給定的字符串中替換單引號(')用雙引號(「),同時保持單引號在收縮配合使用過程的正則表達式的替換梅索德

現在,經過用我自己的方法其實解決這個exercice,我檢查所提出的解決方案是這樣的:

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

正則表達式看起來不錯,它是完全可以理解的,但我無法理解的是替代品的使用主要爲什麼用$2作品?就我所知,這個正則表達式只需要一條路徑,即(^|\W)''(\W|$),這些路徑中的每條路徑只會導致一個捕獲組,因此我們只有$1可用。然而,$2正在捕獲單引號之後的內容,而沒有明確的第二捕獲組在正則表達式中執行此操作。人們可以爭辯說有兩個組,但是再次$2捕獲的是不同於第二組預期的字符串。

我的問題:

  • 爲什麼$2實際上是一個有效的字符串,而不是undefined,什麼是它指的是精確?
  • 這是一個JavaScript RegEx怪癖?
  • 這是否意味着$1, $2...並不總是指明顯的組?
+2

反向引用在每次匹配時都使用空字符串進行初始化,因此如果某個組不匹配,則不會出現問題。這並不是一個怪癖,它符合ES5標準。 –

+0

請詳細解釋爲什麼會發生這種情況?謝謝。 – Acemad

+1

那麼,這是一個有點不同的答案的一部分。以下是[* Backreferences to Failed Groups *]的引用(http://www.regular-expressions.info/backref2.html):*根據ECMA官方標準,對非參與捕獲組的反向引用必須成功沒有任何東西只是反向引用一個沒有捕獲任何東西的參與組。所以,一旦反向引用不參與匹配,它將引用一個空字符串,而不是* undefined *。這不是一個怪癖,只是一個「特徵」。有時候這並不令人期待。 –

回答

1

反向引用在每次匹配時都用一個空字符串進行初始化,所以如果一個組不匹配,就不會有問題。這並不是一個怪癖,它符合ES5標準。

這裏是Backreferences to Failed Groups報價:

根據官方的ECMA標準,反向引用到非參與拍攝組必須成功匹配沒什麼只是一個反向引用到捕獲什麼做了參賽組。

所以,一旦反向引用不參與匹配,它就會引用一個空字符串,而不是未定義的。這不是一個怪癖,只是一個「特徵」。有時候這並不是很期待,但它是如何工作的。

在您的方案中,任何反向引用在匹配時都是空的,因爲有兩個可選分支,每次只有一個匹配。重點是恢復在任一組中匹配的字符。兩個反向引用都被使用,因爲它們中的任何一個都包含要還原的文本,而另一個只包含空白文本。

+1

這幫我清除了一些霧,謝謝。 – Acemad