eErrorT ChainCtrlInitChains(ChainCtrlT* pChainCtrl,
char* name,
int instance)
{
....
}
eErrorT ChainCtrlInit(ChainCtrlT* pChainCtrl, void* pOwner)
{
....
}
我的代码
open(my $FILE, "< a.c") or die $!;
my @arr = <$FILE>;
foreach(@arr){
if ($_ =~ /^ \S+ \s+ \S+ \s* \( (.+?) \) /xsmg) {
my $arg = $1;
my @arr = map /(\w+)$/, split /\W*?,\W*/, $arg;
print my @temp = map "$_\n", @arr
unless $_ =~ /;\s*$/;
}
}
基本上我从函数定义中提取函数参数。
但在这种情况下,我只能提取第二个函数(ChainCtrlInit)的参数而不能提取第一个函数(ChainCtrlinitchains)的参数。
期望的输出
pChainCtrl
name
instance
pChainCtrl
pOwner
输出我正在
pChainCtrl
pOwner
答案 0 :(得分:4)
你遇到的问题是当你做“foreach”时,块中的$ _继承了数组中的每个元素。 例如,
foreach(@arr)..循环的第一次迭代使用“eErrorT ChainCtrlInitChains(ChainCtrlT * pChainCtrl,\ n”)分配$ _,这样你的正则表达式就会失败。
并且您还使用没有太多用途的临时变量。我已经改进了以下代码:
my $arr = do { local $/; <$FILE> }; #Copy one of the comments above.
#note there's a slight difference in the 'while' regex to your code
while ($arr =~ /^ \S+ \s+ \S+ \s* (\( .+? \)) /xsmg) {
my @args = $1 =~ /(\w+)[,)]/g; #This assumes what you want always ends in
#a ',' or a ')', hence the gentle modification in the 'while' regex.
local $" = "\n";
say "@args";
}
答案 1 :(得分:2)
问题在于您是逐行读取文件,因此正则表达式永远不会扩展到多行 - 如果您加载文件然后使其成为带有嵌入新行的单个字符串,它将起作用
例如快速黑客提供
open(my $FILE, "< a.c") or die $!;
my @arr = <$FILE>;
my $file = join('',@arr);
my @matches = $file =~ /^ \S+ \s+ \S+ \s* \( (.+?) \) /xsmg;
foreach (@matches) {
my $arg = $_;
my @arr = map /(\w+)$/, split /\W*?,\W*/, $arg;
print my @temp = map "$_\n", @arr
unless $_ =~ /;\s*$/;
print "\n";
}
答案 2 :(得分:1)
@ Ad-vic,除了@ atleypnorth的解决方案将整个文件篡改成字符串之外,你的split-map语句中可能存在问题。
此
my @arr = map /(\w+)$/, split /\W*?,\W*/, $arg;
应该是这个
my @arr = map /(\w+)\W*$/, split /\W*?,\W*/, $arg;
因为拆分中的最后一个元素会获得剩余字符。
一旦掌握了Perl,您可以将其简化为 -
$/ = "";
open(my $FILE, "< a.c") or die $!;
my $str = <$FILE>;
foreach ( $str =~ /^ \S+ \s+ \S+ \s* \( (.+?) \) /xsmg ) {
print map "$_\n", /(\w+) [^\w,]* (?:,|$)/xg ;
print "\n";
}