Python脚本中split的正确使用及.m转.h文件解析脚本的索引越界问题解决
解决.m文件转.h文件的解析问题
看起来你在处理.m到.h的转换时遇到了几个典型的字符串解析坑——索引越界、分割逻辑不可靠,还有输出格式不符合头文件规范。作为刚接触Python的开发者,这种文本处理的问题很常见,咱们一步步来搞定:
原代码的核心问题
- 行跳过逻辑混乱:你用
for j in InputFile:嵌套readline()的方式会打乱文件指针的位置,很可能跳过了不该跳的行,甚至直接读到文件末尾,后续处理空行时就会触发索引错误。 - 简单分割不可靠:
split(',')没有考虑元素前后的空格、引号,以及行尾的;,一旦遇到空行或者格式稍有偏差的行,分割后的列表长度就会不足,直接抛出IndexError。 - 输出不符合.h规范:当前输出保留了原字符串的引号,也没有按照C头文件的格式(比如变量声明加
;、注释用//)生成内容。
改进后的代码
import re from string import Template # 定义正则表达式,精准匹配每个元素:支持带引号的字符串、数字、数组、空字符串 ELEMENT_PATTERN = re.compile(r''' (?:['"](.*?)['"]|([\d.]+)|\[.*?\]|'') # 匹配带引号内容/数字/数组/空串 ''', re.VERBOSE) def parse_m_line(line): # 清理行尾的分号和空白字符 cleaned_line = line.strip().rstrip(';') if not cleaned_line: return None # 跳过空行 # 用正则提取所有元素 elements = ELEMENT_PATTERN.findall(cleaned_line) # 处理匹配结果:取每个匹配里的非空部分 parsed = [] for elem in elements: for part in elem: if part: parsed.append(part.strip()) break else: parsed.append('') # 校验元素数量,不符合则跳过并警告 if len(parsed) < 6: print(f"警告:行格式错误,已跳过:{line.strip()}") return None return parsed # 主执行逻辑 with open(r'D:\toolchain\Simulink\data\application_parameters_data.m', 'r') as input_file: # 可靠跳过前2行(替换原混乱的跳行逻辑) for _ in range(2): input_file.readline() with open(r'D:\toolchain\Connector\ConDataGenerated.h', 'w') as output_file: # 写入头文件保护和注释 output_file.write("// 自动生成的参数头文件\n") output_file.write("#ifndef CON_DATA_GENERATED_H\n") output_file.write("#define CON_DATA_GENERATED_H\n\n") # 定义符合C规范的变量声明模板 template = Template('$datatype $name = $init_value; // $comment\n') for line in input_file: parsed_elements = parse_m_line(line) if not parsed_elements: continue # 提取所需字段 name = parsed_elements[0] init_value = parsed_elements[1] comment = parsed_elements[4] datatype = parsed_elements[5] # 替换模板并写入文件 output_file.write(template.substitute( datatype=datatype, name=name, init_value=init_value, comment=comment )) # 写入头文件尾部 output_file.write("\n#endif // CON_DATA_GENERATED_H")
关键改进点说明
- 精准的行解析:用正则表达式替代简单的
split(','),不管元素是带引号的字符串、数字还是[0 1]格式的数组,都能准确捕获,彻底避免分割错误。 - 容错处理:自动跳过空行和格式错误的行,同时打印警告信息,不会因为某一行出错导致整个程序崩溃。
- 规范的.h格式:生成符合C语言标准的变量声明,添加了头文件保护(防止重复包含),注释改用
//,变量声明补全了=和;。 - 可靠的跳行逻辑:直接用
for _ in range(2)跳过前2行,文件指针位置不会混乱。 - 路径转义修复:用原始字符串
r'路径'避免了\S等转义字符的问题。
测试后的输出示例
运行改进后的代码,你的输入会生成这样标准的.h内容:
// 自动生成的参数头文件 #ifndef CON_DATA_GENERATED_H #define CON_DATA_GENERATED_H uint16 ManCtrlInputShaftSpeedSwt = 0; // comment single ManCtrlInputShaftSpeedPar = 0; // comment uint16 ManCtrlInputShaftSpeed1Swt = 0; // comment single ManCtrlInputShaftSpeed1Par = 0; // comment uint16 ManCtrlInputShaftSpeed2Swt = 0; // comment single ManCtrlInputShaftSpeed2Par = 0; // comment uint16 ManCtrlOutputShaftSpeedSwt = 0; // comment single ManCtrlOutputShaftSpeedPar = 0; // comment uint16 ManCtrlOutputShaftSpeedDirnSwt = 0; // comment uint16 ManCtrlOutputShaftSpeedDirnPar = 0; // comment uint16 ManCtrlMeasPositionS1Swt = 0; // comment single ManCtrlMeasPositionS1Par = 0; // comment #endif // CON_DATA_GENERATED_H
这样应该就能解决你遇到的索引越界、分割错误和输出格式问题了。如果后续遇到特殊格式的行,只需要微调正则表达式的匹配规则即可。
内容的提问来源于stack exchange,提问作者Denis Kozlov
相关产品推荐
相关产品推荐

