代码之家  ›  专栏  ›  技术社区  ›  John Siracusa

为什么当锚定到字符串的开头时,断言后面的积极外观不起作用?

  •  3
  • John Siracusa  · 技术社区  · 14 年前

    当断言被锚定到字符串的前面时,为什么这个look back断言不起作用?运行下面的代码,您将看到第一个测试通过了,但是第二个测试通过了,这只取决于 ^ 锚定失败。

    use Test::More tests => 2;
    
    my $s = '/123/456/hello';    
    $s =~ s{(?<=/)\d+(?=/\d+/hello)}{0};  # unanchored
    is($s, '/0/456/hello', 'unanchored'); # passes
    
    $s = '/123/456/hello';
    $s =~ s{^(?<=/)\d+(?=/\d+/hello)}{0}; # anchored
    is($s, '/0/456/hello', 'anchored');   # fails
    

    移动

    4 回复  |  直到 14 年前
        1
  •  9
  •   John Siracusa    14 年前

    请记住,断言的宽度为零,并且不使用它匹配的字符。所以锚点必须进入断言内部,否则整个表达式不匹配。

        2
  •  6
  •   Daniel Vandersluis    14 年前

    (?<=/)\d+(?=/hello) 在你的字符串匹配 456 因为它是字符串中两个lookaround都将应用的唯一部分。当你锚定你的表达,它不再可以匹配任何东西。lookaround是零宽度的,所以第二种模式说“匹配从字符串开头开始的一个或多个数字,其中前一个字符是斜杠”,这显然是不可能的。

        3
  •  4
  •   Peter O'Callaghan    14 年前

    我猜是因为(?<=是正的向后看(不是负的),字符串开头之前不能有字符。如果你是在消极向后看,你应该使用(<!相反。

        4
  •  1
  •   Charles    14 年前

    刺的前面没有任何东西,所以任何非空的向后看都会在用^锚定时失败。