Python 在逐行读取文件时保存延伸到多行的值

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也是如此,因此不包含任何实际值。我想在调用值抓取方

我正在写一个小的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
也是如此,因此不包含任何实际值。我想在调用值抓取方法之前,通过搜索“{”在一行中,如果找到了它,那么在包含“{”的行下面的行中找到“;”的下一次迭代,并在任何换行之间找到“;”的下一次迭代,应该删除制表符和空格。 这是我希望该方法在正确运行时显示的输出

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文件解析为字符串通常是一项乏味的工作,很容易出错。您可以尝试使用一些正则表达式,但通常您会发现自己会说:

  • 哦…我从没想过他们能在那里留个空间
  • 如果他们在这里发表评论怎么办
  • 如果有人添加了无用的括号
如果你想构建一些健壮的东西,不要自己解析代码……试着找一些能为你做到这一点的东西。 例如,我会尝试做的是为您的C文件创建一个Swig接口,然后直接访问变量

普通医生:

访问全局变量:

如果你能使用这个解决方案,你唯一要做的就是写几行小的接口文件,把它作为Swig软件的输入,这将为你生成一个python模块,它将封装你的C文件

编辑:

这就是您在您的情况下可以做的:

1.安装Swig 2.创建文件myInterface.i,如下所示:

/* File: myInterface.i */

%include "stdint.i"
%{
#include "file.h"
%}
extern uint8 param1;
extern uint8 param2;
  • 运行命令swig-python myInterface.i这将为您的头文件生成一个python包装器

  • 在Python脚本中导入此文件,并直接从头文件访问变量


  • 我不记得如何处理数组,但它们肯定也可以访问!

    您可以这样尝试:创建一个语句列表和一个包含当前语句的字符串;添加到当前语句,直到它以
    结尾,然后将其添加到语句列表中

    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
    },
    };