正则表达式:从许多比赛中选择最短的比赛

时间:2012-07-06 18:13:34

标签: regex perl

我正在尝试在PERL中编写一个正则表达式来选择最短匹配。我已经写了一个可以识别很多比赛的比赛,但是我需要能够选出所有比赛中最短的比赛。

假设我有以下文字:

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

我可以使用这个正则表达式来识别以BEG开头并以END结尾但没有BEG或END在BEG和END之间的三种情况。

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

它捕获了三个案例。

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

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

我已经考虑将所有匹配拉到数组并确定数组的最短元素。

是否有更简单的方法将其合并到正则表达式中?

提前感谢您的想法和帮助!

1 个答案:

答案 0 :(得分: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;