如何用正则表达式提取C语言中foo_t枚举的键值对
提取C语言枚举foo_t的键值对解决方案
问题分析
你用的正则(?\w+\s*=\s*\d+,*\s*)+}foo_t只抓到最后一行键值对,核心问题是重复捕获组只会保留最后一次匹配结果,而且正则没有限定枚举块的范围,也没处理注释和换行。
正确思路
先定位foo_t对应的整个枚举块,再从块内提取所有键值对,这样不管枚举在文件哪个位置都能精准匹配。
分步实现(以Python为例)
- 匹配foo_t的完整枚举块:用单行模式
(?s)让.匹配换行,精准锁定从typedef enum到}foo_t;的内容 - 提取块内键值对:在匹配到的块里,抓取所有符合
标识符 = 数字格式的行
import re # 示例源码 source = """ typedef enum { /** comment */ A = 1, /** comment */ B = 2, }foo_t; typedef enum { /** comment */ A = 1, /** comment */ B = 2, }bar_t; """ # 1. 捕获foo_t的整个枚举块 foo_block = re.search(r'(?s)typedef enum\s*\{\s*.*?\s*\}foo_t;', source).group() # 2. 提取所有键值对 kv_list = re.findall(r'\w+\s*=\s*\d+,?', foo_block) print(kv_list) # 输出:['A = 1,', 'B = 2,']
单正则直接提取(进阶)
如果想用单正则一次性提取所有键值对,可以用正向预查锁定foo_t块,再全局匹配:
(?s)(?<=typedef enum\s*\{\s*(?:/\*\*.*?\*/\s*)*)\w+\s*=\s*\d+,?(?=(?:\s*/\*\*.*?\*/)*\s*\}foo_t;)
不过分步实现更易读和维护。
原正则问题详解
原正则里的(\w+\s*=\s*\d+,*\s*)+是重复捕获组,正则引擎会不断覆盖捕获组的内容,最终只保留最后一次匹配的B = 2,,这就是A键值对缺失的原因。
内容的提问来源于stack exchange,提问作者Clément
相关产品推荐
相关产品推荐

