用于替换C文件中的#define值的Python脚本

时间:2013-05-16 18:57:05

标签: python parsing

我真的是Python的新手,我正在尝试构建一个脚本来更改#define变量的值。 我的代码似乎工作,但它破坏了输出文件的C缩进。 那么我该如何解决空白问题呢? 任何比我更聪明的建议都将受到高度赞赏!

KEYWORDS=["PERIOD","PWM_RATE","DUTY_OFFSET","MAX_DUTY"]
VALS=[3,3,3,3]    
import re
f1 = open('../src/in.c','r')
f2 = open('../src/out.xc','w')
for line in f1:
    s=line.split()
    if len(s)> 1 and s[1] in KEYWORDS:
        s[2] = VALS[1]
    f2.write(' '.join(s)+'\n')
f1.close()
f2.close()

4 个答案:

答案 0 :(得分:3)

使用regex,因为它会保持行中单词之间的原始间距:

使用with语句处理文件,因为它会自动为您关闭文件。

with open('../src/in.c','r') as f1, open('../src/out.xc','w') as f2:
    for line in f1:
        if line.startswith("#define"):
            s=line.split()
            if s[1] in KEYWORDS:
                val = str(VALS[1])
                line = re.sub(r'({0}\s+)[a-zA-Z0-9"]+'.format(s[1]),r"\g<1>{0}".format(val),line)
        f2.write(line)

<强>输入:

#define PERIOD  100
#define PWM_RATE  5
#define DUTY_OFFSET  6
#define MAX_DUTY             7
#define PERIOD 2     5000000

#include<stdio.h>  
int main()  
{  
    int i,n,factor;  
    printf("Enter the last number of the sequence:");  
    scanf("%d",&j);
} 

<强>输出:

#define PERIOD  3
#define PWM_RATE  3
#define DUTY_OFFSET  3
#define MAX_DUTY             3
#define PERIOD 3     5000000

#include<stdio.h>
int main()
{
int i,n,factor;
printf("Enter the last number of the sequence:");
scanf("%d",&j);
}

答案 1 :(得分:1)

您可以在字符串中使用replace,而不是对整个源文件进行标记,如下所示:

for line in f1:
    for i in range(len(KEYWORDS)):
        line = line.replace("#define " + KEYWORDS[i], "#define " + KEYWORDS[i] + " " + str(VALS[i]))
    f2.write(line)

实际上,这对已经有值的变量不起作用,它不会替换它们的旧值只附加到它们。

所以OP建议的解决方案不是替换行中的字符串,而是简单地重写整行,如下所示:

for line in f1:
    for i in range(len(KEYWORDS)):
        if line.startswith("#define") and KEYWORDS[i] in line:
            line = "#define " + KEYWORDS[i] + " " + str(VALS[i])+"\n"
    f2.write(line)

另一种解决方案是使用正则表达式(re.sub()而不是line.replace()

答案 2 :(得分:1)

类似的东西:

replace = {
    'PERIOD': '3'
}

with open('/home/jon/blah.txt') as fin, open('/home/jon/blah2.txt', 'w') as fout:
    lines = (line.strip() for line in fin)
    for line in lines:
        parts = line.split(None, 2)
        if parts[0].lower() == '#define':
            parts[2] = replace.get(parts[1], parts[2])
            fout.writeline(' '.join(parts) + '\n')
        else:
            fout.writeline(line + '\n')

所以这只会以#define开头的行 - 而下一个空格的任何内容都是要查找的名称,如果在替换中找到,则会替换该值,否则,只需保留原样即可

答案 3 :(得分:0)

我认为问题是.split()将忽略前导空格。

我会使用正则表达式捕获前导空格并将输出附加到它捕获的内容:

import re
line ='\t#define x'
split = line.split()
begin = re.match('^\s', line)
print(line[begin.start():begin.end()]+' '.join(split))