0

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

$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)

当我void [s|S]et[\w]+\(\s*.*string 通过诸如www.regextester.com之类的正则表达式测试器运行正则表达式(输入为:)时,所有这些都匹配(是的,我知道它们只匹配“字符串”的结尾。这就是我想要的)。

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

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

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

在包含如下行的文件上运行时工作正常:

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

(不是正则表达式的唯一区别是在“void”之前添加了“inline”。文件中唯一的区别是在“void”之前添加了“inline”。

编辑 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";
}
4

2 回答 2

8

$fh在您的第二个grep.

这段代码:

grep { ... } <$fh>

耗尽 $fh,读取文件中的所有行。当您下一次调用grep { ... } <$fh>时,没有更多行可以匹配,因为$fh它位于文件末尾。

于 2013-09-19T17:04:58.433 回答
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)
于 2013-09-19T16:50:16.657 回答