2013-05-16 42 views
1

我对Python真的很陌生,我正在尝试构建一个脚本来更改#define变量的值。 我的代码似乎工作,但它遗失输出文件的C缩进。 那么我该如何解决空白问题呢? 任何建议比我更聪明的实施将不胜感激!替换C文件中的#define值的Python脚本

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() 

回答

1

相反令牌化的整个源文件,你也许可以只使用替换字符串,像这样的:

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()

+0

是的,这就是我的意思,对不起。我有另一个错误,我应该将替换的返回值赋给原始字符串,在它应该工作之后,我将编辑我的帖子。 – anana

+0

Thanx的快速反应,但我仍然得到一个定义线,如 ** #define PERIOD 2 \t \t \t 5000000 **这将是正确的,如果我们以某种方式删除“** 2 ** – Dimitris

+0

我不是我确信我明白了这个问题,但是我在替换行中存在一个缺失的缺陷,我修复了它,代码适用于我。对于错误 – anana

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); 
} 
+0

那么,这个代码失败,没有我添加的len(s)> 1,但也不会取代新文本上的任何东西。它可能是正则表达式的错误? – Dimitris

+1

@Dimitris我已经修复了我的代码,它现在应该可以工作。 –

+0

当然!我仍然在尝试不同的事情:-) – Dimitris

0

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

我会使用一个正则表达式来捕获前导空格和追加的输出到它捕获:

import re 
line ='\t#define x' 
split = line.split() 
begin = re.match('^\s', line) 
print(line[begin.start():begin.end()]+' '.join(split)) 
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 - 任何直到下一个空格的东西都是要查找的名称,如果在替换中找到,将替换该值,否则,就按原样保留。