如何从Dataform的.sqlx文件提取完整config块并转为Python字典
解决Dataform .sqlx文件config块提取的嵌套大括号匹配问题
你的问题根源在于原正则用[^}]*匹配内容,遇到嵌套的}就会提前终止,无法处理config块内的子结构(比如bigquery配置)。要匹配嵌套的大括号,需要用递归正则表达式来平衡嵌套结构。
解决方案步骤
1. 使用支持嵌套匹配的正则表达式
Python的re模块支持递归匹配,用(?R)可以递归调用整个正则模式,从而处理任意深度的嵌套大括号。
匹配config块的正则:
r'config\s*({(?:[^{}]|(?R))*})'
config\s*: 匹配config关键字及后续任意空白(包括换行)({(?:[^{}]|(?R))*}): 捕获整个config块的大括号内容:(?:[^{}]|(?R))*: 匹配非大括号字符,或者递归匹配完整的大括号结构(处理嵌套)
2. 提取并解析为Python字典
Dataform的config语法类似JS对象(允许无引号键、单引号),标准json库无法直接解析,推荐用json5库(兼容JS对象语法)。
完整代码示例
import re import json5 # 读取.sqlx文件内容 with open("your_target.sqlx", "r", encoding="utf-8") as f: file_content = f.read() # 可选:清理config块中的注释(避免解析报错) # 移除单行注释 file_content = re.sub(r'//.*$', '', file_content, flags=re.MULTILINE) # 移除块注释 file_content = re.sub(r'/\*.*?\*/', '', file_content, flags=re.DOTALL) # 匹配所有config块 config_regex = re.compile(r'config\s*({(?:[^{}]|(?R))*})', re.DOTALL) config_matches = config_regex.findall(file_content) # 解析每个config块为Python字典 for config_str in config_matches: try: config_dict = json5.loads(config_str) print("解析后的config字典:") print(config_dict) except Exception as e: print(f"解析失败:{e}")
3. 依赖安装
如果没有json5库,先通过pip安装:
pip install json5
注意事项
- 递归正则支持Python 2.5及以上版本,主流环境都兼容
- 如果config块中有复杂注释或特殊字符,建议先做清理再匹配,避免解析报错
- 若不想用第三方库,可手动将config语法转为标准JSON(给无引号键加双引号、替换单引号为双引号),但这种方式容易遗漏边界情况,不如
json5可靠
内容的提问来源于stack exchange,提问作者Marcelo Gazzola
相关产品推荐
相关产品推荐

