2

我正在尝试在 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

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

我考虑过将所有匹配项拉到一个数组中并确定数组中最短的元素。

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

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

4

1 回答 1

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;
于 2012-07-06T18:44:15.223 回答