1

特定の一致を否定的な後ろ向きで動作させるのに問題があります

@list = qw( apple banana cherry); 
$comb_tlist = join ("|", @list);
$string1 = "include $(dir)/apple";
$string2 = "#include $(dir)/apple";

if( $string1 =~ /^(?<!#).*($comb_tlist)/)   #matching regex I tried, works kinda

配列には、文字列と照合される一連の変数が保持されます。

$string1 に一致する正規表現が必要ですが、$string2 には一致しません。$string1 に一致しますが、$string2 にも一致します。ここで私が間違っていることを誰かに教えてもらえますか。ありがとう!

4

4 に答える 4

5

問題は、負の後読み行頭^が両方ともゼロ幅の一致であることです。だからあなたが言うとき

「文字列の先頭から開始」

そして言う

「その前の文字が # でないことを確認してください」

...実際には、文字列の開始前の文字をチェックします。それは何もないので、もちろんそう#ではありません。

代わりに先読みを使用してください。これは機能します:

use strict;
use warnings;

my @list = qw( apple banana cherry); 
my $comb_tlist = join ("|", @list);
my $string1 = 'include $(dir)/apple';
my $string2 = '#include $(dir)/apple';

if( $string1 =~ /^(?!#).*($comb_tlist)/)  { say "String1"; }
if( $string2 =~ /^(?!#).*($comb_tlist)/)  { say "String2"; }

サンプル コードで 4 つの重大な間違いを犯したことに注意してください。まずstring1、文字列として解釈されるベアワードである which を使用します。次に、宣言し@listてから使用します@tlist。第三に、あなたは使用していません(使用していないようです)

use strict;
use warnings;

これらのプラグマによってエラーが通知される可能性がありますが、プラグマがなければ、最初の 2 つの重大なエラーについて警告されなかった可能性があります。それらを使用しない正当な理由はないので、将来的には使用してください。

第四に、宣言

$string1 = "include $(dir)/apple";

文字列内の変数を補間しようとすることを意味します$($は二重引用符で囲まれた文字列のメタ文字であるため、単一引用符を使用する必要があります。

my $string1 = 'include $(dir)/apple';
于 2012-12-14T23:16:29.030 に答える
2

否定の後読みは必要ありません。そうでない最初の文字に一致するだけです#

use strict;
use warnings;

my @list = qw( apple banana cherry); 
my $comb_tlist = join ("|", @list);
my $string1 = "include dir/apple";
my $string2 = "#include dir/apple";

for ($string1, $string2) {
  print "match:$_\n" if( /^[^#].*($comb_tlist)/);
}

また、リテラルに一致させる場合は、記号をバックスラッシュで$(dir)エスケープする必要があり$ます。そうしないと、スカラー変数を示します。この場合、Perl コードに"$(dir)"する必要があります。\$(dir)

于 2012-12-14T23:09:20.973 に答える
2

いくつかの問題:

  • 常に使用しますuse strict; use warnings;
  • string1意図した場所の使用を修正します$string1
  • 必要に応じて使用して、上記で検出されたスコープ エラーを修正しますmy
  • @list変数名 ( vs )のタイプミスを修正します@tlist
  • $(変数を補間するつもりはなかったと思います。
  • #文字列の最初の文字の前にa が見つかることはないので/^(?<!#).* .../、意味がありません。それは単に意味し/^.* .../ます。あなたはおそらく欲しかった/^[^#].* .../
于 2012-12-14T23:11:48.590 に答える
0

複雑な正規表現は、2 つまたは 3 つに分割するだけで簡単になることがあります。最初のステップでコメント文字列を除外します。

于 2012-12-14T23:12:19.247 に答える