2016-02-15 203 views
1

在Perl的重複組,我試圖捕捉字作爲從下面的例子中字符串的標記(總是會有至少一個字):正則表達式:捕獲組(Perl的)

"red"    ==> $1 = 'red'; 
"red|white"   ==> $1 = 'red'; $2 = 'white'; 
"red|white|blue" ==> $1 = 'red'; $2 = 'white'; $3 = 'blue'; 
etc. 

圖案我在這裏看到的是:WORD,後跟n套 「| WORD」[N> = 0]

所以從這,我有:

/(\ W +)((?:\ |) (\ w +)*)/

根據我的理解,它總是與第一個WORD相匹配,如果存在| WORD對,則根據需要多次捕獲它。

這不工作,雖然,我已經試過像幾個版本:

/^(\ w +)(\ |(\ w +))* $/

...我錯過了什麼?

+2

你不能像這樣做。當你重複一個捕獲組時,前一個匹配被新的覆蓋(每次重複)。你爲什麼不使用分割? –

+0

您可以使用Python PyPi正則表達式,.NET Regex(CapureCollection)實現該功能,並且有一個選項可用於獲取Boost正則表達式庫中的捕獲。 –

+0

@WiktorStribiżew:你也可以用Perl正則表達式來實現這一點 - 而不是OP所嘗試的方式。 – ruakh

回答

2

你的第一個正則表達式實際上是錯誤的—是*在錯誤的地方—但我會專注於自己的第二正則表達式,這是正確的:

/^(\w+)(\|(\w+))*$/ 

的問題是,這個正則表達式有三個捕捉組:(\w+)(\|(\w+))(\w+)。因此,它至多會填充三個匹配變量:$1,$2$3。每個匹配變量對應於單個相應的捕獲組。這不是你想要的。

你應該做的,而不是爲使用split

my @words = split /\|/, "red|white|blue"; 

# now $words[0] is 'red', $words[1] is 'white', $words[2] is 'blue' 
+0

感謝您的迴應。 編輯:所以這是不可能與正則表達式做到這一點? 那麼:/ ^(\ w +)(\ | \ w +)*?$/ –

+0

@JesseWalton:正則表達式中捕獲組的數量是正則表達式的靜態/詞彙屬性,並且不依賴於字符串匹配。如果您需要可變數量的捕獲組,則單個正則表達式匹配不適合您。 (''red | white | blue'=〜m/^(\ w +)(\ |(\ w +))* $ /'就像是寫'$ 1 ='red'; $ 2 ='| white'; $ 3 ='白色'; $ 2 ='| blue'; $ 3 ='blue'',它不斷重複使用相同的捕獲變量。) – ruakh