Perl正则表达式匹配但不包括可选的结束标记

时间:2014-03-08 10:52:47

标签: regex perl

我正在努力有效地匹配行,但不包括可选的结束令牌。

/(.*)(?:$tok)?/

不起作用。结束标记是可选的,因此是最终的?,然后是第一组 贪婪地抓住它。

/(.*?)(?:$tok)?/

也不起作用:第一组匹配零长度字符串

我能做的最好的事情是

my $tok = 'end';
while (<>) {
    my ($line) = /
       (?|             # 'branch reset'
           (.*)$tok    # either a line terminated with the end token
         |             # or
           (.*)        # the whole line
       )               # end branch reset group
    /x;
    print $line, "\n";
}

这很有效,但效率低下让我感到震惊。正则表达式引擎必须解析该行两次,这是我试图避免的。

我知道使用index()可以更好地解决所述问题:

my $i = index($_, $end);
$line = $i < 0 ? $_ : substr $_, 0, $i;

但是我需要对线进行其他处理,使正则表达式成为可取的 - 无论如何,我认为这是一个学习机会; - )

2 个答案:

答案 0 :(得分:1)

请查看以下示例。这是在匹配结尾或行尾(great)处寻找单词$

my $str = 'alexander the great alex';
if ($str =~ m/(.*?)(?=great|$)/i) {
    print "$1";
}

您可以将以上示例中的$token替换为great

答案 1 :(得分:0)

这应该有效 -

/^(.*?)(?:(?:\b$tok)?$)/gm

演示here