我想要一个正则表达式来匹配除了更广泛的表达式中的一些特定选项之外的所有内容。
以下示例将匹配test_foo.pl或test_bar.pl或test_baz.pl:
/test_(foo|bar|baz)\.pl/
但我喜欢恰恰相反:
match test_.*\.pl except for where .* = (foo|bar|baz)
我对此的选择有限,因为这不是直接进入perl程序,而是cloc, a program that counts lines of code (that happens to be written in perl)的参数。所以我正在寻找一个可以在一个正则表达式中完成的答案,而不是多个链接在一起。
答案 0 :(得分:6)
您应该能够通过使用否定前瞻来实现这一目标:
/test_(?!foo|bar|baz).*\.pl/
如果foo
,bar
或baz
紧跟test_
后,这将失败。
请注意,这仍然可能与test_notfoo.pl
匹配,并且会在test_fool.pl
上失败,如果您不想要这种行为,请通过添加一些确切应该和不应该匹配的示例来澄清。< / p>
如果您想接受test_fool.pl
或test_bart.pl
之类的内容,则可以将其更改为以下内容:
/test_(?!(foo|bar|baz)\.pl).*\.pl/
答案 1 :(得分:1)
#!/usr/bin/env perl
use strict; use warnings;
my $pat = qr/\Atest_.+(?<!foo|bar|baz)[.]pl\z/;
while (my $line = <DATA>) {
chomp $line;
printf "%s %s\n", $line, $line =~ $pat ? 'matches' : "doesn't match";
}
__DATA__
test_bar.pl
test_foo.pl
test_baz.pl
test baz.pl
0test_bar.pl
test_me.pl
test_me_too.txt
输出:
test_bar.pl doesn't match test_foo.pl doesn't match test_baz.pl doesn't match test baz.pl doesn't match 0test_bar.pl doesn't match test_me.pl matches test_me_too.txt doesn't match
答案 2 :(得分:1)
(?:(?!STR).)*
是
STR
作为
[^CHAR]
是
CHAR
所以你想要
if (/^test_(?:(?!foo|bar|baz).)*\.pl\z/s)
更具可读性:
my %bad = map { $_ => 1 } qw( foo bar baz );
if (/^test_(.*)\.pl\z/s && !$bad{$1})
答案 3 :(得分:0)
你会否定匹配运算符。例如:
perl -lwe "print for grep ! m/(lwp|archive).*\.pl/, glob q(*.pl)"
# Note you'd use single-quotes on Linux but double-quotes on Windows.
# Nothing to do with Perl, just different shells (bash vs cmd.exe).
!
否定了比赛。以上是简写:
perl -lwe "print for grep ! ($_ =~ m/(lwp|archive).*\.pl/), glob q(*.pl)"
也可以使用否定匹配运算符!~
编写,如下所示:
perl -lwe "print for grep $_ !~ m/(lwp|archive).*\.pl/, glob q(*.pl)"
如果您想知道,glob
只是用于根据您的示例获取文件名的输入列表。我只是替换了另一种适合我在目录中使用的文件的匹配模式。