2013-10-02 54 views
1

我的正則表達式應匹配a,b,cd或字符x的任何序列;字符串"abcdxabcd"應該有三個單獨的匹配"abcd","x""abcd"圓括號分組如何影響正則表達式結果?

我不明白以下正則表達式之間的差異,我正在尋找圓括號如何影響結果的詳細說明。對於測試字符串"abcdxabcd"

  1. /[abcd]+|x/這一個似乎工作。接下來的四個沒有。
  2. /(d|[abc])+|x/返回三個匹配組{d},{[空]},和{d}
  3. /(d|[abc]+)+|x/返回三個匹配組{d},{[空]},和{d}
  4. /(d|[abc]+)+|(x)/返回三個匹配組{d,[空]},{[空],x}和{d,[空]}
  5. /((d|[abc]+)+|(x))/返回三個匹配組{{abcd,d,[empty]},{x,[empty] ,x}和{abcd,d,[空]}

我並不完全熟悉匹配組的概念,這是我的問題的一部分。我的目標不是找到一個表達工作的表達,以便理解這些案例之間的差異,並理解那些不起作用的實際做法。

+1

你能展示一些你的測試用例嗎?爲什麼最後四項工作沒有完成(即,它們與第一項工作匹配的是什麼)?乍一看,他們應該 - 無論如何,他們都會匹配你的字符串「abcdxabcd」。 – iamnotmaynard

+0

來自a-d的任何一組字符都應該是一個匹配的一部分。字符x應該是另一個匹配的一部分。任何其他出現的字符都不應該匹配。 – Kvass

+0

你使用'String#scan'來獲得這些匹配嗎? – iamnotmaynard

回答

0

========= /[abcd]+|x/

這絕對作品,這個表達式與[abcd]+|匹配的x[abcd]+匹配字母a,b,cd的一個或多個組合。 x匹配文字x

所以,當你運行它針對abcdxabcd[abcd]+第一場比賽abcd,然後x匹配字面x然後[abcd]+第二abcd匹配。

現在你是完全正確的,那些都是單獨的比賽,換句話說,如果你使用/^[abcd]+|x$/爲正則表達式(注意錨^$你會發現,這將不匹配abcdxabcd

========= /(d|[abc])+|x/

這是一個完全不同的表達。 (d|[abc])+d[abc]相匹配,並捕獲捕獲組號1內的任何匹配項,但由於+因此捕獲組包含最後一個與其內部內容匹配的內容,所以該表達式重複一次或多次。

所以,當你運行這個對abcdxabcda[abc]然後b過,然後c匹配過,但後來dd匹配,這是由整個羣體相匹配的最後一件事(d|[abc])+所以d是值與組匹配,因此匹配組1,即d

現在來到x,它與x匹配,並且該組沒有捕獲任何東西,因此第二個捕獲組是空的。我們得到:{d},{}{d}

我可以繼續解釋表達式的其餘部分,但這需要大量的輸入。我希望你能看到這對其他人是如何工作的。

摘要:當一組不匹配,它抓住了空字符串(我不知道如果這實際上是在Ruby代碼發生,或者它只是通過Rubular爲了清晰顯示)。最後一個被某個羣體捕獲的東西是持續的,如果該羣組匹配很多次,那麼以前的捕獲就會消失。

編輯:捕獲組簡單的捕捉或會記住裏面的表達式匹配了,所以你可以參考它無論是在通過反向引用的正則表達式本身或引用它的替換字符串。

aha我忘了告訴你,捕獲組從1開始編號,並從左到右計數。

讓我給你舉個例子:如果你想以匹配後自己立即重複字符,你可以使用:

(.)\1 

.單個字符,()捕捉什麼在第1組匹配的匹配,那麼我們嘗試使用\1匹配與組1匹配的相同內容,該內容稱爲反向引用。

另一個例子:假設您想要匹配一個以破折號分隔的多個字符,如下所示:abc-53並且您希望在替換字符串中引用它們。

你會匹配:匹配一個或多個字符未飛奔-,現在我們使用的是在替換字符串捕獲這樣

([^-]+)-([^-]+) 

([^-]+)

$2 == $1 

這將導致將abc-53轉換爲53 == abc

捕獲組和其他正則表達式功能的主題可能需要很多解釋,您可以檢查regular-expressions.info以獲取更多信息。

+0

您可以充實一下捕捉組的細節以及它們的工作原理嗎? – Kvass

+0

@Kvass我編輯了我的答案,請檢查編輯。 –

相關問題