Perl中的负面观察断言

Uno*_*nos 5 regex perl

我有一组文件路径,我想列出所有不包含的文件路径x/y/z/.另一个限制是我无法使用,print if !m{x/y/z/}因为我没有对脚本的写权限.我可以为脚本提供regexp模式以包含(作为命令行选项),即匹配的所有内容都将被打印.

这是我的尝试.我想匹配的行具有x/y/z/在他们面前.

#!/usr/bin/perl
use warnings;
use strict;

while(<DATA>) {
   print if m{(?<!x/y/z/).*};
}

__DATA__
x/y/z/a/b/x.cc
x/y/z/a/b/x.cc
x/y/z/a/b/x.cc
x/y/a/b/m.cc
x/y/a/b/m.cc
Run Code Online (Sandbox Code Playgroud)

我的期望是它只打印底部的两个字符串,但它会打印所有内容.但是当我将模式更改为时(?<=x/y/z/).*,它只打印前3个字符串:

x/y/z/a/b/x.cc
x/y/z/a/b/x.cc
x/y/z/a/b/x.cc
Run Code Online (Sandbox Code Playgroud)

为什么这样,我该怎么做来修复我的正则表达式?

Tud*_*tin 4

你需要的是消极的前瞻。所以,答案直接从修道院传来:

#!/usr/bin/perl
use warnings;
use strict;

while(<DATA>) {
   print if m{^(?!(?s:.*)x/y/z)}; 
}

__DATA__
x/y/z/a/b/x.cc
x/y/z/a/b/x.cc
x/y/z/a/b/x.cc
x/y/a/b/m.cc
x/y/a/b/m.cc
Run Code Online (Sandbox Code Playgroud)

  • 直译:匹配*不*以任意数量的任意字符开头,后跟“x/y/z”的字符串 (2认同)
  • 您真的想过滤掉“x/y/zoo/a.cc”吗?需要添加 `/` 或 `(?:/|\z)`。 (2认同)