模式匹配结果不一致

时间:2015-08-05 18:51:21

标签: regex perl

我将模式/\*与字符串匹配,包含/*。有时它有效,有时却没有,我不明白为什么。这是代码:

my @tokens = ( "//", "/\\*", "\\*/", "\"", "\\\"", "#if", "#ifdef", "#elif", "#else", "#endif" );
for( my $i = 0; $i < scalar @tokens; $i++ )
{
    print "Matching \'$tokens[$i]\' against \'$_\'\n";

    if( /$tokens[$i]/g )
    {
        print "Match: \'$&\', pos = ", pos(), "\n";
    }
}

以某种方式,字符串"abc // /* */ " \" #if // "匹配@tokens中的所有模式,但字符串"abc /* */ " \" #if // "匹配/*以外的所有模式。我错过了什么? 非常感谢提前!

2 个答案:

答案 0 :(得分:0)

if (/.../g)毫无意义 [1] 。由于我不明白的原因,人们不断尝试使用它。大多数情况下,使用这个有缺陷的代码不会导致任何不利影响。不幸的是,它确实适合你。

if( /$tokens[$i]/g )

应该是

if( /$tokens[$i]/ )

至于确定比赛的位置,

  • $-[0]会告诉您比赛的开始位置。
  • $+[0]会告诉你比赛的长度。
  • $-[0] + $+[0]会告诉您比赛的结束时间。
  1. 高级用户有时可能会使用if (/.../gc),但此处不合适。

答案 1 :(得分:0)

首先,让我以一种更易于阅读的方式重写您的代码:

    my @tokens = ( '/', '/*', '*/', '"', '\"', '#if', '#ifdef', '#elif', '#else', '#endif' );
    my $test_string = 'abc /*  */ " \" #if //';
    foreach (split(/\s/,$test_string)) {
            for (my $i = 0; $i < scalar @tokens; $i++ ) {
                  print "Matching  \'$tokens[$i]\' against \'$_\'\n";
                  if( /\Q$tokens[$i]\E/g )  {
                            print "Match: \'$&\', pos = ", pos(), "\n";
                  }
            }
            print "\n";
    }

只要您使用存储在变量中的正则表达式,就可以使用上面的quotemeta(/\Q ... \E/)组合。你不必逃脱这么多角色。

访问Perldoc获取更多信息:quotemeta

我了解到您尝试计算正则表达式(在@tokens中)与测试字符串匹配的次数,这就是您使用/g和函数pos()的原因。但是,/g仅导致模式/*导致问题。如果省略上面的ikegami回答的全局修饰符g,它应该与你匹配,但pos()将不起作用。