正则表达式匹配最短的字符串

时间:2014-12-12 15:40:49

标签: regex perl

如果我有字符串

zeta alpha alpha beta charlie delta

如何提取alpha beta

如果我使用alpha(.+?)beta,则会返回alpha alpha beta

4 个答案:

答案 0 :(得分:2)

这个怎么样?

alpha(?:(?!\balpha\b).)*?beta

DEMO

  • alpha匹配字符串alpha
  • (?:(?!\balpha\b).)*?会对任何字符进行非贪婪的匹配,但不能进行alpha,不能进行零次或多次。 \b在单词字符和非单词字符之间匹配的单词边界。
  • beta匹配字符串beta

答案 1 :(得分:1)

我觉得这个问题还有更多,但是

怎么样
/(alpha\s+beta)/

如果您希望 last alpha的{​​{1}}跟随beta,那么

beta

答案 2 :(得分:1)

怎么样:

use Modern::Perl;
use Data::Dump qw(dump);

my $re = qr/(alpha(?:(?!alpha).)*?beta)/;
while(<DATA>) {
    chomp;
    my @res = $_ =~ /$re/g;
    dump@res;
}

__DATA__
zeta alpha alpha beta charlie delta
zeta alpha alpha beta charlie alpha delta    

<强>输出:

"alpha beta"
"alpha beta"

答案 3 :(得分:0)

如果我理解正确,您需要最短的匹配字符串,该字符串以alpha开头,以beta结尾。没有“标准”正则表达式可以在每种情况下都这样做,我怀疑即使Perl的各种正则表达式增强功能也不允许它(除非你用(?{...})一直跳回到程序代码中),因为即使找到了一些不包含任何内部alpha的候选匹配,除非匹配正好是alpha beta,否则仍有可能发生更短的匹配。例如,在alpha charlie beta alpha beta中,正则表达式引擎如何知道跳过第一个匹配(alpha charlie beta)并继续查找,以便稍后找到alpha beta

让我们以艰难的方式去做。假设字符串在$_

push @x, [pos, $&] while /alpha|beta/g;   # Find all end positions
foreach (@x) {
    if ($_->[1] eq 'alpha') {
        $lastAlpha = $_;
    } elsif (defined $lastAlpha) {
        $d = $_->[0] - $lastAlpha->[0];
        @best = ($d, $lastAlpha->[0]) if !@best || $d < $best[0];
    }
}

print substr($_, $best[1] - 5, $best[0] + 5) if @best;