Python 在逐行读取文件时保存延伸到多行的值
我正在写一个小的python脚本,它从dir中的几个.c文件中读取参数及其值。参数通常具有以下格式:Python 在逐行读取文件时保存延伸到多行的值,python,python-2.7,Python,Python 2.7,我正在写一个小的python脚本,它从dir中的几个.c文件中读取参数及其值。参数通常具有以下格式: uint8 param1 = 1; sint8 param2 = 2; 但是,有时它们可能是这样的: param3 = { 1, 2, 3, 4, 5, 6 }; 甚至: param4 = { 1, 2, 3, { 4, 5, 6 }, }; 正如您所怀疑的,在涉及param3和param4的情况下,行将是param3={,对于param4也是如此,因此不包含任何实际值。我想在调用值抓取方
uint8 param1 = 1;
sint8 param2 = 2;
但是,有时它们可能是这样的:
param3 = {
1, 2, 3,
4, 5, 6
};
甚至:
param4 = {
1, 2, 3,
{
4, 5, 6
},
};
正如您所怀疑的,在涉及param3和param4
的情况下,行将是param3={
,对于param4
也是如此,因此不包含任何实际值。我想在调用值抓取方法之前,通过搜索“{”在一行中,如果找到了它,那么在包含“{”的行下面的行中找到“;”的下一次迭代,并在任何换行之间找到“;”的下一次迭代,应该删除制表符和空格。
这是我希望该方法在正确运行时显示的输出
param3 = {1,2,3,4,5,6};
param4 = {1,2,3,{4,5,6},};
这就是我正在使用的布局,formatFile(line)
正是我需要帮助的方法
for root, dirs, files in os.walk(PATH_DST_SOURCE):
for file in files:
if file.endswith('.c'):
with open(os.path.join(root, file), 'r') as this:
for line in this:
formatFile(line)
不幸的是,我不知道如何做到这一点,我希望得到一些帮助,甚至是在正确的方向上推动一下。当然,如果有更好的方法来解决我的问题,那么这些也是受欢迎的!你可以尝试一种简单的方法(不必逐行阅读):
提出一个完全不同的解决方案……只要稍微考虑一下…… 将C文件解析为字符串通常是一项乏味的工作,很容易出错。您可以尝试使用一些正则表达式,但通常您会发现自己会说:
- 哦…我从没想过他们能在那里留个空间
- 如果他们在这里发表评论怎么办
- 如果有人添加了无用的括号
/* File: myInterface.i */
%include "stdint.i"
%{
#include "file.h"
%}
extern uint8 param1;
extern uint8 param2;
我不记得如何处理数组,但它们肯定也可以访问!您可以这样尝试:创建一个语句列表和一个包含当前语句的字符串;添加到当前语句,直到它以
;
结尾,然后将其添加到语句列表中
with open("file.c") as f:
statements = []
cur = ""
for line in f:
cur += line.strip()
if cur.endswith(";"):
statements.append(cur)
cur = ""
当然,这是假设每个以
;
结尾的语句实际上都在行尾,而不是,例如,后面跟着一个行注释或另一个语句(部分)。如果您还想处理这些情况,事情会变得复杂得多(如行注释中的代码、块注释或字符串中的代码等语句)您可能应该查找一些现有的解析器库。使用正则表达式:
import re
pattern = r'((?P<type>\w+)\s+)?(?P<name>\w+)\s*=\s*(?P<value>.+?);'
with open("example.c") as cfile:
assignments = []
for m in re.finditer(pattern, cfile, re.DOTALL):
dic = m.groupdict()
dic["value"] = dic["value"].replace("\n", " ")
assignments.append(dic)
print assignments
…对于此输入文件:
uint8 param1 = 1;
sint8 param2 = 2;
param3 = {
1, 2, 3,
4, 5, 6
};
param4 = {
1, 2, 3,
{
4, 5, 6
},
};
在这个中为行使用
是行不通的,因为您正在查看的结构跨越多行否?所以您只需要过滤掉[type]name=(number |“{”list of numbers”}形式的所有变量定义
或者您解析文件还有什么其他目的?Will;
总是以行结尾,或者另一个语句可以以同一行开头吗?正如Stefano的回答所解释的,这是很难正确完成的,特别是当.c
文件可能包含注释,或者参数可以包含字符串时。但是如果您可以保证.c
文件没有包含';“
的注释或字符串。您可以使用一种简单的方法。我不确定OP是否知道他可以一次读取整个文件。因此,应该建议这样做。这似乎是对我来说最简单的解决方案,而且我对python的知识有限。我之所以逐行阅读,是因为这样更容易对于我来说,当脚本要执行其他命令时。我读取整个文件没有问题,也许我应该提到-这是我的错-我没有考虑过。我会回来并正确标记它,谢谢!请注意,如果;
在字符串或注释中,这可能会失败;而且,我认为拆分可以简化这一点直接用;
替换,而不是先用\n
替换?如其他答案中所述,如果字符串或注释包含“;”则此操作失败字符。所有语句都以结尾;后面什么也没有。这对我来说似乎足够简单,谢谢。这正是我的想法。这使我的脚本有点复杂,但我通过它了解了很多关于python的知识。然而,这对我来说似乎太复杂了,我大约3周前开始用python编写代码,我所做的事情很容易用c语言编写ode。我会在以后记住这条评论,因为我相信我会通过它找到有价值的信息,谢谢!嗯……我认为这实际上比你正在做的更容易。我可以在我的描述中为你添加一些额外的信息。:)
uint8 param1 = 1;
sint8 param2 = 2;
param3 = {
1, 2, 3,
4, 5, 6
};
param4 = {
1, 2, 3,
{
4, 5, 6
},
};