2011-08-14 34 views
6

有沒有一種方便的方法來編寫一個正則表達式,儘可能匹配正則表達式有正則表達式儘可能保持匹配嗎?

實施例:

my $re = qr/a ([a-z]+) (\d+)/; 

match_longest($re, "a") =>() 
match_longest($re, "a word") => ("word") 
match_longest($re, "a word 123") => ("word", "123") 
match_longest($re, "a 123") =>() 

即,$re被認爲是正則表達式的一個序列,並且match_longest嘗試儘可能多的該序列的匹配。從某種意義上說,匹配永遠不會失敗 - 這只是匹配成功的問題。一旦正則表達式匹配失敗,undef爲不匹配的部分。

我知道我可以編寫一個函數,它需要一系列正則表達式並創建一個正則表達式來執行match_longest的工作。這裏有一個想法的概要:

假設你有三個正則表達式:$r1,$r2$r3。單正則表達式來執行match_longest的工作將具有以下結構:

$r = ($r1 $r2 $r3)? | $r1 ($r2 $r3) | $r1 $r2 $r3? 

不幸的是,這是在正則表達式的數量平方。是否有可能更高效?

+0

改變的例子正則表達式,因爲'123'比賽' \ w +' – ErikR

回答

5

您可以使用它包含了只有一次每個正則表達式正則表達式

$r = ($r1 ($r2 ($r3)?)?)? 

。在本例中,您也可以使用非捕獲組(?:...)以不干擾您的原始正則表達式。

+0

這隻會在存在尾隨空格時正確捕捉零件。 –

2

如果我理解這個問題,使用嵌套組,?應該工作:

my $re = qr/a ((\w+) (\d+)?)?/; 
+0

這個正則表達式並不完全匹配'單詞'。 –

0

這種特殊情況下,可以這樣寫:

m/a (?:(\w+)(?: (\d+))?)?/