如何在Python中清除.jbeam文件nodes属性内容(不使用JSON解析器)
如何用Python高效清除.jbeam文件中nodes属性的内容?
我处理的是.jbeam文件,这类文件基于JSON但采用自定义格式,支持注释、省略元素间逗号等标准JSON不允许的规则,因此无法使用标准JSON解析器。我的需求很简单:清空文件中nodes属性的内容,同时保留原文件的整体格式——原格式对可读性至关重要,用标准JSON工具会打乱格式,导致行数剧增,阅读困难。试过几种方法都没成功,想知道怎么用Python高效完成这个任务。
示例输入(简化版.jbeam)
sample_jbeam = ''' { "partname": { "refNodes": [ ["ref:", "back:", "left:", "up:", "leftCorner:", "rightCorner:"], ["ref", "", "", "", "", ""] ], "nodes": [ ["id", "posX", "posY", "posZ"], ["ref", 0, 0, 0], ["b1", 1.0, 1.0, 1.0], ], "beams": [ ], } } '''
期望输出
{ "partname": { "refNodes": [ ["ref:", "back:", "left:", "up:", "leftCorner:", "rightCorner:"], ["ref", "", "", "", "", ""] ], "nodes": [], "beams": [ ], } }
失败的尝试
尝试1:正则表达式
用正则匹配替换但无效,代码如下:
import re pattern = r'("nodes":\s*)\[.*?\]' # cleaned_text = re.sub(pattern, r'\1[]', sample_jbeam, flags=re.DOTALL) cleaned_text = re.sub(r'"nodes": \[.*?\]', '"nodes": []', sample_jbeam, flags=re.DOTALL) print(cleaned_text)
问题在于非贪婪匹配.*?会在遇到第一个]就停止,但nodes数组内部还有嵌套的[],导致匹配不完整。
尝试2:io.StringIO
尝试用io.StringIO()逐行处理,但.jbeam的格式复杂性让这种方法失效。
尝试3:JSON预处理器
使用能将.jbeam转为有效JSON的预处理器,但转换后会完全打乱原文件的格式,不符合需求。
可行解决方案
方法1:改进的正则表达式(适配嵌套结构)
针对nodes数组的嵌套结构,调整正则规则,匹配从"nodes": [开始到对应闭合]的完整内容:
import re def clean_nodes(jbeam_text): # 匹配"nodes": [ ... ],兼容内部嵌套的一维数组 pattern = r'("nodes":\s*)\[(?:[^\[\]]|\[[^\[\]]*\])*\]' return re.sub(pattern, r'\1[]', jbeam_text, flags=re.DOTALL) # 测试 cleaned = clean_nodes(sample_jbeam) print(cleaned)
这个正则通过匹配“非括号字符”或“无嵌套的括号对”,精准定位nodes数组的完整范围,适用于示例及多数常规.jbeam结构。
方法2:基于行的状态机处理
如果正则无法应对更复杂的嵌套,可采用逐行遍历+状态标记的方式,完全保留原格式:
def clean_nodes_line_by_line(jbeam_text): lines = jbeam_text.split('\n') in_nodes = False result = [] for line in lines: stripped = line.strip() # 进入nodes数组范围 if stripped.startswith('"nodes": ['): in_nodes = True # 替换为空数组格式,保留原行缩进 result.append(line.replace(stripped, '"nodes": []')) elif in_nodes: # 检测到nodes数组闭合,退出状态 if stripped in (']', '],'): in_nodes = False # 跳过nodes数组内的所有行 continue else: result.append(line) return '\n'.join(result) # 测试 cleaned = clean_nodes_line_by_line(sample_jbeam) print(cleaned)
该方法通过标记是否处于nodes数组内部,跳过所有数组内的行,只保留"nodes": []的行,完全兼容.jbeam的自定义格式。
内容的提问来源于stack exchange,提问作者Megan Love
相关产品推荐
相关产品推荐

