2

正規表現を、より広い表現内のいくつかの特定のオプションを除いてすべてに一致させたいです。

次の例は、test_foo.pl、test_bar.pl、またはtest_baz.plと一致します。

/test_(foo|bar|baz)\.pl/

しかし、私は正反対のことを望みます:

match test_.*\.pl except for where .* = (foo|bar|baz)

これは直接perlプログラムではなく、コードの行数をカウントするプログラム(perlで記述されている)であるclocへの引数であるため、このオプションには制限があります。したがって、複数の正規表現を連鎖させるのではなく、1つの正規表現で実行できる答えを探しています。

4

4 に答える 4

6

ネガティブ先読みを使用することで、これを達成できるはずです。

/test_(?!foo|bar|baz).*\.pl/

、、またはの直後に続く場合foo、これは失敗します。barbaztest_

これはまだのようなものtest_notfoo.plと一致する可能性があり、失敗することに注意してtest_fool.plください。この動作を望まない場合は、正確に一致する必要があるものと一致しないものの例をいくつか追加して明確にしてください。

test_fool.plまたはのようなものを受け入れたい場合はtest_bart.pl、次のように変更できます。

/test_(?!(foo|bar|baz)\.pl).*\.pl/
于 2012-05-16T21:11:43.527 に答える
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が一致しません
test_foo.plが一致しません
test_baz.plが一致しません
テストbaz.plが一致しません
0test_bar.plが一致しません
test_me.plが一致します
test_me_too.txtが一致しません

于 2012-05-16T21:45:42.467 に答える
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})
于 2012-05-17T04:48:07.223 に答える
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は単に例のようにファイル名の入力リストを取得するために使用されます。ディレクトリ内の便利なファイルに適した別の一致パターンに置き換えました。

于 2012-05-16T21:18:21.870 に答える