求Python正则表达式精准识别C函数体开头并插入注释的方案
解决C函数体开头识别及注释插入的正则优化方案
现有正则的问题分析
你的原有正则存在两个核心问题:
- 开头的
[^(if|else|switch|for|if\s+|else\s+|switch\s+|for\s+)]写法错误——正则的字符集[]仅作用于单个字符,无法用来排除完整的关键字短语,导致对if/else等语句的排除逻辑完全失效。 .*是贪婪匹配且无法处理嵌套括号,遇到if(MACRO(expa) && MACRO(expb)) {这类带嵌套括号的语句时,会直接匹配到最后一个),导致错误截取内容。
优化后的正则方案
针对C函数的语法特征,我们需要实现两个核心逻辑:排除if/else/switch/for关键字开头的语句、正确匹配带嵌套括号的函数参数列表。
正则表达式(Python 3.10+)
利用Python 3.10支持的递归子模式处理嵌套括号,同时通过负向预查排除关键字:
import re # 定义正则模式,使用VERBOSE模式提高可读性,MULTILINE处理多行 func_pattern = re.compile(r''' ^\s* # 匹配行开头的任意空格(支持缩进的函数) (?!(if|else|switch|for)\b) # 负向预查:排除以指定关键字开头的行 [\s\S]*? # 非贪婪匹配函数修饰符、返回类型、函数名(支持跨多行的函数头部) (\((?:[^()]|(?2))*\)) # 递归匹配括号内的参数,完美处理嵌套括号 \s* # 匹配括号后的空格或换行 \{ # 匹配函数体的左大括号 ''', re.VERBOSE | re.MULTILINE)
注释插入实现
通过re.sub实现匹配后插入指定注释:
def insert_function_comment(c_code: str, comment: str = '/* my comment */') -> str: # 将匹配到的函数头部+{替换为原内容+换行+注释 return func_pattern.sub(r'\g<0>\n{}'.format(comment), c_code)
测试示例
输入C代码
static my_struct1* alloc_mem (my_struct2* a) { // 函数内容 } if(MACRO(expa) && MACRO(expb)) { // 条件语句,不会被匹配 } void test_func(int x, MACRO(y, nested(z))) { // 带多层嵌套参数的函数 } // 跨多行的函数头部 extern void cross_line_func(char* arg1, int arg2) { // 跨多行函数 }
输出结果
static my_struct1* alloc_mem (my_struct2* a) { /* my comment */ // 函数内容 } if(MACRO(expa) && MACRO(expb)) { // 条件语句,不会被匹配 } void test_func(int x, MACRO(y, nested(z))) { /* my comment */ // 带多层嵌套参数的函数 } // 跨多行的函数头部 extern void cross_line_func(char* arg1, int arg2) { /* my comment */ // 跨多行函数 }
注意事项
- 依赖Python 3.10+:递归子模式是Python 3.10新增的特性,若使用旧版本Python,可通过
(\((?:[^()]+|\([^()]*\))*\))替代递归子模式,但仅能处理一层嵌套括号。 - 语法边界:无法处理极端复杂的C语法(如函数指针作为参数、宏定义的非常规函数头部),但可覆盖绝大多数常规函数定义场景。
- 跨多行支持:正则中使用
[\s\S]*?替代.*?,确保可以匹配跨多行的函数头部。
内容的提问来源于stack exchange,提问作者Nox Player
相关产品推荐
相关产品推荐

