如何用正则表达式匹配C语言特定指针赋值语句并提取表达式?
解决C代码中特定赋值语句的正则匹配问题
我来帮你搞定这个正则匹配的需求!你要捕捉的是(*((_type*)expressionA)) = expressionB;(或外层带括号的((*((_type*)expressionA)) = expressionB);)这种格式的C代码行,提取其中的expressionA和expressionB。
原正则的问题
你之前的正则[*][(][\s]*[(\s]*.*[*][)\s]*(.*)\s*[)]\s*=(.*)[\s]*;存在几个关键问题:
- 用了贪婪的
.*,会过度匹配,导致无法正确区分类型部分和表达式部分 - 没有处理表达式中嵌套的括号(比如
expressionA里的(type01_01_06_offset * 1)) - 没有考虑类型前的修饰符(比如
volatile、unsigned) - 无法兼容语句外层带括号的情况(比如结尾的
);)
改进后的正则(PCRE兼容)
针对你的场景,我写了一个支持嵌套括号、覆盖修饰符和两种结尾格式的正则:
^\s*\(\*\(\((?:[\w_]+\s+)*[\w_]+\*\)\((?<exprA>(?:[^()]|(\((?<DEPTH>)|\)(?<-DEPTH>)))*)(?(DEPTH)(?!))\)\)\s*=\s*(?<exprB>(?:[^();]|(\((?<DEPTH2>)|\)(?<-DEPTH2>)))*)(?(DEPTH2)(?!))\s*[);]\s*$
正则各部分解析
让我拆解一下这个正则的核心逻辑:
^\s*:匹配行首的任意空白字符(适配代码缩进)\(\*\(\(:精准匹配开头的(*(((?:[\w_]+\s+)*[\w_]+\*:匹配类型部分,支持带修饰符的类型(比如volatile unsigned short*),[\w_]+匹配C语言的标识符,(?:...)是非捕获组用来重复匹配修饰符(?<exprA>(?:[^()]|(\((?<DEPTH>)|\)(?<-DEPTH>)))*)(?(DEPTH)(?!)):捕获expressionA,用PCRE的平衡组语法处理嵌套括号,确保括号完全匹配,避免误截断\)\):匹配类型转换后的))\s*=\s*:匹配等号前后的任意空白(?<exprB>(?:[^();]|(\((?<DEPTH2>)|\)(?<-DEPTH2>)))*)(?(DEPTH2)(?!)):捕获expressionB,同样用平衡组处理嵌套括号,同时排除结尾的分号/括号加分号\s*[);]\s*$:匹配结尾的;或);,以及行尾的空白
测试验证
用你给出的两个测试案例验证:
- 代码行:
(*((volatile unsigned short*)(type01_01_06_base + (type01_01_06_offset * 1))) = (unsigned short)(unsigned long)0x01010101);- 捕获的
exprA:type01_01_06_base + (type01_01_06_offset * 1) - 捕获的
exprB:(unsigned short)(unsigned long)0x01010101
- 捕获的
- 代码行:
(*((volatile unsigned char*)add)) = (unsigned char)data;- 捕获的
exprA:add - 捕获的
exprB:(unsigned char)data
- 捕获的
注意事项
- 这个正则依赖PCRE的平衡组特性,所以要确保你使用的正则引擎支持(比如Python的
regex库、Perl、PHP,或者主流在线正则工具的PCRE模式);如果用Python标准库的re,需要换用递归解析等替代方案 - 如果代码中有字符串、注释,这个正则会失效,建议先对代码做预处理(去除注释、字符串)
- 对于非常复杂的类型定义(比如带括号的typedef),可能需要微调类型部分的匹配规则,但基本能覆盖绝大多数常见场景
内容的提问来源于stack exchange,提问作者Thuy Nguyen
相关产品推荐
相关产品推荐

