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"; }

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

use strict;
use warnings;

这些 pragma 可能会通知您您的错误,如果没有它们,您很可能不会收到关于前两个严重错误的警告。没有充分的理由不使用它们,所以在将来这样做。

四、申报

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

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

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

You don't need negative lookbehind, just match a first character that is not #:

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)/);
}

Also, if you mean to match a literal $(dir), then you need to escape the $ sign with a backslash, otherwise it denotes a scalar variable. If this is the case, "$(dir)" should be \$(dir) in Perl code.

于 2012-12-14T23:09:20.973 回答
2

一些问题:

  • 始终使用use strict; use warnings;.
  • 修正string1where you mean 的使用$string1
  • my通过在适当的地方使用来修复上述检测到的范围错误。
  • 修正变量名称 ( @listvs @tlist) 中的拼写错误。
  • 我确定您并不是要对$(变量进行插值。
  • 你永远不会#在字符串的第一个字符之前找到 a,所以/^(?<!#).* .../没有意义。它只是意味着/^.* .../。你可能想要/^[^#].* .../
于 2012-12-14T23:11:48.590 回答
0

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

于 2012-12-14T23:12:19.247 回答