我有一个问题,试图使用某种匹配来处理负面看法
例如
@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。任何人都可以告诉我这里我错了什么。谢谢!
答案 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在第一步中注释了字符串。