我正在尝试在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
我想只匹配第二个,因为它是三个中最短的。
我已经考虑将所有匹配拉到数组并确定数组的最短元素。
是否有更简单的方法将其合并到正则表达式中?
提前感谢您的想法和帮助!
答案 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;