2012-07-06 23 views
2

我想在PERL中寫一個正則表達式來選擇最短匹配。我寫了一篇可以識別很多比賽的文章,但我需要能夠挑選所有比賽中最短的一篇。正則表達式:從衆多比賽中挑選最短的匹配

讓說我有以下文字:

$text = "blah BEG blah blah blah END blah blah BEG blah END blah BEG blah blah END"; 

我可以用這個正則表達式來確定的三種情況,與BEG開始並沒有任何BEG或END BEG和END之間END結束。

/(BEG(?:(?!BEG|END).)*END)/ 

它捕獲了三種情況。

BEG blah blah blah END 
BEG blah END 
BEG blah blah END 

我只想匹配第二個,因爲它是三個中最短的。

我曾考慮將所有匹配拉到數組中,並確定數組中最短的元素。

有沒有更簡單的方法將其納入正則表達式?

在此先感謝您的寶貴意見和幫助!

+0

您可以使用非貪婪的'*'如下所示:'*?'。也許這對你有用。 – cha0site 2012-07-06 18:17:34

回答

2
use List::Util qw(reduce); 

my $shortest = 
    reduce { length($a) < length($b) ? $a : $b } 
     /(BEG(?:(?!BEG|END).)*END)/s; 

這是可以做到完全在一個Perl的正則表達式(與嵌入式Perl代碼的幫助),但是這將是愚蠢的,除非你絕對需要。

my ($shortest) =/
    (BEG (?:(?!BEG|END).)* END) 
    (?! 
     .* 
     (BEG (?:(?!BEG|END).)* END) 
     (?(?{ length($2) >= length($1) })(*FAIL)) 
    ) 
/sx;