2013-06-11 43 views
3

從本質上講,這是我想做的事:正則表達式重複:如何匹配變長度的表達式?

if ($expression =~ /^\d{num}\w{num}$/) 
{ 
    #doSomething 
} 

其中num不是標識符,但可以站在大於0(\d\w被任意選擇)的任意整數。我想匹配一個字符串,如果它包含兩組相關字符,一組緊跟在另一組之後,並且每組中的字符數相同。

在這個例子中,123abc021202abcdef將匹配,但43abc不肯起來,也將12ab3c1234acbcde

回答

6

不要以爲字符串的從左至右增長,而是從外面:

xy 
x(xy)y 
xx(xy)yy 

你的正則表達式將則是這樣的:

/^(x(?1)?y)$/ 

哪裏(?1)是對外部括號的引用。 ?使它成爲可選的,以便給出遞歸匹配的「基本情況」。這可能是如何使用正則表達式來匹配context-free grammars的最簡單的例子 - 儘管使用解析器生成器或解析器組合器庫通常更容易。

+0

有趣。雖然perldoc.perl.org說:「警告:這個擴展的正則表達式功能被認爲是實驗性的,可能會在沒有通知的情況下進行更改。」 – aschepler

+1

您必須將它錨定(例如用'^ .. \ z'或'(?<!x)..(?! y)')來獲得所需的效果。 – ikegami

+0

我期望*一些*注意在這一點上。 – ikegami

4

嗯,有

if ($expression =~ /^(\d+)([[:alpha:]]+)$/ && length($1)==length($2)) 
{ 
    #doSomething 
} 

一個正則表達式並不總是最好的選擇。

+0

我正在考慮用'm // gc'和'\ G'鏈接2場比賽,但你的方式會更好。您可能希望將'^'和'$'作爲nix,因爲它們可能超過所需的OP。 – tjd

+0

@tjd:但是如果你沒有任何錨點,那麼''43abc''實際上是匹配的,因爲它包含'「3a」'。我認爲不言而喻,如果你想用它作爲一個更大的正則表達式,你可以使用'^'和/或'$'。 – aschepler

+0

'm/^(?> \ d +)(\ w +)$ /'解決了123a會匹配的問題,因爲'3'是'\ w' – tjd