如何用Python正确读写特定格式的.cfg配置文件?
处理含重复键、数组/嵌套JSON的.cfg文件读写方案
这类.cfg文件不符合标准INI格式(存在重复键、非标准的数组/JSON结构),所以configparser、libconf这类标准/专用库无法直接处理。以下是两种实用解决方案:
方案一:正则+JSON轻量解析(适合结构不复杂的场景)
利用正则匹配键值对,借助JSON解析器处理数组和嵌套对象,同时手动处理重复键的列表存储。
解析函数
import re import json def parse_cfg(file_path): cfg_data = {} with open(file_path, 'r', encoding='utf-8') as f: lines = f.readlines() idx = 0 while idx < len(lines): line = lines[idx].strip() idx += 1 # 跳过空行和注释 if not line or line.startswith('#'): continue # 匹配键值对 match = re.match(r'^(\w+)\s*=\s*(.*)$', line) if not match: continue key, value_str = match.groups() # 处理跨多行的JSON结构(数组/对象) if (value_str.startswith('{') and not value_str.endswith('}')) or (value_str.startswith('[') and not value_str.endswith(']')): while idx < len(lines): next_line = lines[idx].strip() value_str += next_line idx += 1 if (value_str.startswith('{') and value_str.endswith('}')) or (value_str.startswith('[') and value_str.endswith(']')): break # 解析值类型 try: value = json.loads(value_str) except json.JSONDecodeError: # 处理字符串、数字 if value_str.startswith(('"', "'")) and value_str.endswith(('"', "'")): value = value_str[1:-1] else: try: value = int(value_str) except ValueError: try: value = float(value_str) except ValueError: value = value_str # 处理重复键:转成列表存储 if key in cfg_data: if not isinstance(cfg_data[key], list): cfg_data[key] = [cfg_data[key]] cfg_data[key].append(value) else: cfg_data[key] = value return cfg_data
写入函数
def write_cfg(data, file_path): with open(file_path, 'w', encoding='utf-8') as f: for key, value in data.items(): # 重复键逐行输出 if isinstance(value, list): for item in value: f.write(f"{key} = {serialize_value(item)}\n") else: f.write(f"{key} = {serialize_value(item)}\n") def serialize_value(value): # 序列化不同类型的值 if isinstance(value, (dict, list)): return json.dumps(value, indent=4) elif isinstance(value, str): return f'"{value}"' else: return str(value)
说明
- 支持跨多行的嵌套JSON/数组解析
- 自动将重复键的值转为列表
- 兼容性好,无需额外安装依赖
方案二:pyparsing语法解析(适合复杂结构场景)
如果.cfg文件有更复杂的语法(比如特殊注释、多行字符串、自定义语法规则),可以用pyparsing构建专用解析器,可靠性更高。
步骤1:安装依赖
pip install pyparsing
解析函数
from pyparsing import Word, alphas, nums, QuotedString, Forward, Group, ZeroOrMore, Suppress, Literal, Optional # 定义语法元素 identifier = Word(alphas, alphas + nums + '_') integer = Word(nums).setParseAction(lambda t: int(t[0])) float_num = Word(nums + '.').setParseAction(lambda t: float(t[0])) string = QuotedString('"') | QuotedString("'") # 递归定义数组和对象 array = Forward() object_ = Forward() value = string | float_num | integer | array | object_ array << Literal('[').suppress() + ZeroOrMore(value + Suppress(Optional(','))) + Literal(']').suppress() object_ << Literal('{').suppress() + ZeroOrMore(Group(identifier + Suppress('=') + value) + Suppress(Optional(','))) + Literal('}').suppress() # 定义键值对规则 key_value = Group(identifier + Suppress('=') + value) cfg_parser = ZeroOrMore(key_value) def parse_cfg_pyparsing(file_path): with open(file_path, 'r', encoding='utf-8') as f: content = f.read() parsed = cfg_parser.parseString(content) cfg_data = {} for key, value in parsed: # 处理重复键 if key in cfg_data: if not isinstance(cfg_data[key], list): cfg_data[key] = [cfg_data[key]] cfg_data[key].append(value) else: cfg_data[key] = value return cfg_data
写入函数
可复用方案一中的write_cfg和serialize_value函数,逻辑一致。
说明
- 可自定义扩展语法规则(比如添加注释支持、特殊字符处理)
- 解析精度更高,适合复杂格式的.cfg文件
内容的提问来源于stack exchange,提问作者OsRaMoSaO
相关产品推荐
相关产品推荐

