我正在尝试编写一个正则表达式来识别单行文本,并将下划线(_)识别为行继续符。例如,“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或更多”的延续!
我做错了什么?
答案 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 | ...