2013-05-16 18 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 - 任何直到下一個空格的東西都是要查找的名稱,如果在替換中找到,將替換該值,否則,就按原樣保留。