【问题标题】:Negative lookbehind assertion in PerlPerl 中的否定后向断言
【发布时间】:2012-11-09 05:12:40
【问题描述】:

我有一组文件路径,我想列出所有不包含x/y/z/ 的文件路径。另一个限制是我不能使用print if !m{x/y/z/},因为我没有脚本的写权限。我可以向 include 提供带有正则表达式模式的脚本(作为命令行选项),即所有匹配的内容都会被打印出来。

这是我的尝试。我正在尝试匹配没有在它们之前有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

我的期望是它只会打印底部的两个字符串,但它会打印所有内容。但是当我将模式更改为 (?&lt;=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

为什么会这样,我应该如何修复我的正则表达式?

【问题讨论】:

  • m{(?&lt;!x/y/z/).*} 匹配 x/y/z/a/b/x.cc 因为 m{(?&lt;!x/y/z/).*} 匹配 /y/z/a/b/x.cc

标签: regex perl


【解决方案1】:

您需要的是否定的前瞻。所以,直接从the monastery 得到答案:

#!/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

【讨论】:

  • 直译:匹配一个以任意数量的任意字符开头后跟x/y/z的字符串
  • 您真的是要过滤掉x/y/zoo/a.cc吗?需要添加/(?:/|\z)
  • 不,我不想过滤掉x/y/zoox/y/z/ 下的所有内容都应该被过滤掉。让我适当地编辑问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-02
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多