为什么这个正则表达式在测试时匹配,而不是在perl中?

时间:2013-09-19 16:26:26

标签: regex perl grep

我有一个正则表达式,我需要确定某些函数类型是否在文件中。像这样:

$stringsetexists = grep {/void [s|S]et[\w]+\(\s*.*string/} <$fh>;

这是从perl文件运行的,尝试在.cpp文件中匹配以下函数:

void setChanName(const std::string & chanName)
void setChanNameFont(const std::string & font)
void setOSDMessage(const std::string & osdMessage)
void setOSDMessageFont(const std::string & font)

当我通过正则表达式测试程序(例如www.regextester.com)运行正则表达式(输入为:void [s|S]et[\w]+\(\s*.*string)时,所有这些匹配(是的,我知道它们只匹配&#34的结尾;字符串&#34;。这就是我想要的东西。

但是,当我在perl脚本中运行上述命令时,它找不到匹配项。我知道脚本正在打开文件,所以不是问题。我知道perl脚本中的其他正则表达式。有什么问题?

编辑:混淆问题,以下正则表达式:

 $stringsetexists = grep {/inline void [s|S]et[\w]+\(\s*.*string/} <$fh>;

在包含如下行的文件上运行时效果很好:

 inline void setIPv6Address(const std::string & ipv6Address)

(不是正则表达式的唯一区别是添加&#34;内联&#34;之前&#34; void&#34;。文件中的唯一区别是添加&#34;内联&#34;之前&#34; void&#34;。

编辑2 :扩展我已经放置的内容,相关的代码块在这里:

open $fh, "<", $file;
$stringsetexists = grep {/inline void [s|S]et[\w]+\(\s*.*string/} <$fh>; #this works for all files that contain "inline void"
if ($file eq "OSDSettings.h") #I know this part runs, because the print statement inside properly prints out that it is in OSDSettings.h
{
    $stringsetexists = grep {/void [s|S]et[\w]+\(\s*.*string/} <$fh>;
    print $file." opened: ".$stringsetexists."\n";
}

2 个答案:

答案 0 :(得分:8)

在第二个$fh之前快退或重新打开grep

此代码:

grep { ... } <$fh>

耗尽 $fh,读取文件中的所有行。当您下次呼叫grep { ... } <$fh>时,没有其他行可供匹配,因为$fh位于文件末尾。

答案 1 :(得分:2)

http://codepad.org/ldgWVTsm

看起来它对我有用,但请注意您要循环浏览文件,而不是将文件句柄(<$fh>)放在最后。

注意:这应该是评论,而不是答案,但答案是你没有问题。


根据评论和其他答案,我更新了示例以说明如何重用文件句柄。但是,有更好的方法可以做到这一点,所以这纯粹是例如:

http://codepad.org/jfxt1YOd

use strict;

my $fh       = *DATA;            # set the filehandle
my $pos      = tell $fh;         # store file pos

## Positive Matches

my @matched  = grep {/void [s|S]et[\w]+\(\s*.*string/} <$fh>;

print "Found: " . @matched . "\n";
print "Matches:\n @matched";


# Reset the position to use again
seek $fh, $pos, 0;

## Negative Matches

my @not_matched = grep {$_ !~ /void [s|S]et[\w]+\(\s*.*string/} <$fh>;

print "Found: " . @not_matched . "\n";
print "Not Matched:\n @not_matched";

__DATA__
viod setChanName(const std::string & chanName)     # Notice the misspelling
void setChanName(const std::string & chanName)
void setChanNameFont(const std::string & font)
void setOSDMessage(const std::string & osdMessage)
void setOSDMessageFont(const std::string & font)