这是否违反了“最左边最长”的原则?

时间:2010-06-27 14:05:38

标签: regex perl

我正在尝试编写一个正则表达式来识别单行文本,并将下划线(_)识别为行继续符。例如,“foo_ \ nbar”应该被视为一行,因为“foo”以下划线结尾。我在尝试:

$txt = "foo_\nbar";
print "$&\n" if $txt =~ /.*(_\n.*)*/;

然而,这仅打印:

foo_

这似乎违反了Perl regexes的“最左边最长”规则!

有趣的是,如果我删除正则表达式中的最后一个星号(*),即:

$txt = "foo_\nbar";
print "$&\n" if $txt =~ /.*(_\n.*)/;

确实打印:

foo_
bar

但是我需要明星认出“0或更多”的延续!

我做错了什么?

3 个答案:

答案 0 :(得分:6)

@ysth解释了为什么会发生这种情况。要修复它,您可以使用以下正则表达式:

/([^_\n]|_.)*/s

答案 1 :(得分:5)

Perl不做“最左边最长”;相反,每个正则表达式功能都有明确定义的行为方式。只要正则表达式的其余部分完全匹配,您的初始*将尽可能多地匹配。为防止它吞咽_,请执行以下操作:

/(.*(?!(?<=_)\n)_\n)*.*/

答案 2 :(得分:1)

正则表达式设计有两种基本风格:

POSIX定义最左边最长的味道。例如:将任何“a | b”更改为“b | a”对完全匹配没有任何作用。

PERL定义左偏味。每个“a | b”检查左分支“a”,如果这匹配,则从不检查“b”。因此,“a | b”与“b | a”很少相同。这里的*就像()| a | aa | aaa | aaaa | ...