perl负面看与分组背后

时间:2012-12-14 23:01:55

标签: regex perl grouping

我有一个问题,试图使用某种匹配来处理负面看法

例如

@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 个答案:

答案 0 :(得分: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"; }

请注意,您在示例代码中犯了四个严重错误。首先,使用string1这是一个单词,它将被解释为一个字符串。其次,您声明@list,然后使用@tlist。第三,你没有(似乎)使用

use strict;
use warnings;

这些pragma可以告诉你你的错误,如果没有它们,你很可能不会被告知你的前两个关键错误。没有充分的理由不使用它们,所以将来也一样。

第四,宣言

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

表示您尝试在字符串中插入变量$($是双引号字符串中的元字符,因此您应该使用单引号:

my $string1 = 'include $(dir)/apple';

答案 1 :(得分: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),则需要使用反斜杠转义$符号,否则它表示标量变量。如果是这种情况,则"$(dir)"在Perl代码中应为\$(dir)

答案 2 :(得分:2)

一些问题:

  • 始终使用use strict; use warnings;
  • 修正string1使用$string1的位置。
  • 在适当情况下使用my修复上述检测到的作用域错误。
  • 修改变量名称中的拼写错误(@list vs @tlist)。
  • 我确定你不是要插入$(变量。
  • 你永远不会在字符串的第一个字符前找到#,所以/^(?<!#).* .../毫无意义。它只是意味着/^.* .../。你可能想要/^[^#].* .../

答案 3 :(得分:0)

如果你只是将它们分成两三个,那么复杂的正则表达式变得微不足道。 Filterout在第一步中注释了字符串。