You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl正则匹配多行C可变参数函数调用的问题求助

解决Perl正则匹配跨多行C可变参数函数调用并提取第四个参数的问题

原正则的问题分析

  1. [^\)\(,]+ 字符集不匹配换行符,导致跨多行的func1调用无法被捕获;
  2. 递归组写法有误(多余的||应该改为|);
  3. 没有正确分组来定位并提取第四个参数。

解决方案一:手动解析参数列表(更可靠)

对于带嵌套括号的参数,纯正则拆分容易出问题,手动解析参数列表能更好处理复杂场景,同时支持跨多行匹配:

perl -n -0777 -e '
while (/func1\s*\(\s*(.*?)\s*\)/gs) {
    my $args = $1;
    my $count = 0;
    my $current_arg = "";
    my $depth = 0;
    my $fourth_arg;
    foreach my $char (split //, $args) {
        if ($char eq "(") { $depth++ }
        elsif ($char eq ")") { $depth-- }
        elsif ($char eq "," && $depth == 0) {
            $count++;
            if ($count == 3) {
                $fourth_arg = "";
            } elsif ($count > 3) {
                last;
            }
            $current_arg = "";
            next;
        }
        $current_arg .= $char if $count >= 3;
    }
    if (defined $fourth_arg) {
        $fourth_arg =~ s/^\s+|\s+$//g;
        my $line_num = 1 + ($` =~ tr/\n//);
        print "$ARGV:$line_num: $fourth_arg\n";
    }
}
' test.c

关键说明:

  • -0777 将整个文件读入内存,避免逐行处理的限制;
  • /func1\s*\(\s*(.*?)\s*\)/gs 匹配所有func1调用,s修饰符让.匹配换行,g全局匹配;
  • 手动遍历参数字符,通过括号深度$depth区分嵌套括号内的逗号和参数分隔逗号,计数到第四个参数;
  • 通过统计匹配结果前的换行符数量计算行号,输出文件名、行号和清理后的第四个参数。

测试输出:

test.c:2: d
test.c:4: d
test.c:5: d
test.c:6: d

解决方案二:递归正则提取第四个参数(适合简单场景)

如果你的代码没有注释、字符串内特殊字符等复杂情况,可以用递归正则匹配参数,直接捕获第四个:

perl -n -0777 -e '
my $arg_re = qr/(?:[^(),]+|\((??{$arg_re})\))+/;
while (/func1\s*\(\s*(?:$arg_re\s*,\s*){3}($arg_re)/gs) {
    my $fourth = $1;
    $fourth =~ s/^\s+|\s+$//g;
    my $line_num = 1 + ($` =~ tr/\n//);
    print "$ARGV:$line_num: $fourth\n";
}
' test.c

关键说明:

  • $arg_re 是递归正则,匹配单个参数(包括带嵌套函数调用的参数);
  • (?:$arg_re\s*,\s*){3} 匹配前三个参数及后续的逗号和空白;
  • ($arg_re) 直接捕获第四个参数,后续清理空白并输出位置信息。

内容的提问来源于stack exchange,提问作者HardcoreHenry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:09:16