代码之家  ›  专栏  ›  技术社区  ›  JoelFan

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

  •  3
  • JoelFan  · 技术社区  · 14 年前

    我正在尝试编写一个正则表达式来识别一行文本,其中下划线(\)被识别为行延续字符。例如,“foo\unbar”应视为一行,因为“foo”以下划线结尾。我正在尝试:

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

    但是,这只打印:

    foo_
    

    这似乎违反了Perl正则表达式的“最左最长”规则!

    有趣的是,如果我去掉正则表达式中的最后一颗星(*),即:

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

    打印:

    foo_
    bar
    

    但是我需要星星来识别“0或更多”的连续体!

    3 回复  |  直到 14 年前
        1
  •  6
  •   ZyX    14 年前

    @ysth解释了为什么会这样。要修复它,可以使用以下正则表达式:

    /([^_\n]|_.)*/s
    
        2
  •  5
  •   ysth    14 年前

    /(.*(?!(?<=_)\n)_\n)*.*/
    
        3
  •  1
  •   Chris Kuklewicz    14 年前

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

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

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