我正在努力有效地匹配行,但不包括可选的结束令牌。
/(.*)(?:$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;
但是我需要对线进行其他处理,使正则表达式成为可取的 - 无论如何,我认为这是一个学习机会; - )
答案 0 :(得分:1)
请查看以下示例。这是在匹配结尾或行尾(great
)处寻找单词$
。
my $str = 'alexander the great alex';
if ($str =~ m/(.*?)(?=great|$)/i) {
print "$1";
}
您可以将以上示例中的$token
替换为great
。
答案 1 :(得分:0)