2014-02-14 131 views
0

我想用正則表達式在文件中找到文本,並將其替換爲其他名稱後。我必須先逐行讀取文件,因爲在其他方面,re.match(...)無法找到文本。用正則表達式查找文本並替換爲文件

我的測試文件,在這裏我想提出modyfications是(無所有,我刪除了一些代碼):

//... 
#include <boost/test/included/unit_test.hpp> 
#ifndef FUNCTIONS_TESTSUITE_H 
#define FUNCTIONS_TESTSUITE_H 
//... 
BOOST_AUTO_TEST_SUITE(FunctionsTS) 
BOOST_AUTO_TEST_CASE(test) 
{ 
    std::string l_dbConfigDataFileName = "../../Config/configDB.cfg"; 
    DB::FUNCTIONS::DBConfigData l_dbConfigData; 
//... 
} 
BOOST_AUTO_TEST_SUITE_END() 
//... 

現在Python代碼,可取代configDB名到另一個。我必須通過正則表達式來查找configDB.cfg名稱,因爲名稱一直在變化。只有名字,擴展名不需要。

代碼:

import fileinput 
import re 

myfile = "Tset.cpp" 

#first search expression - ok. working good find and print configDB 
with open(myfile) as f: 
    for line in f: 
    matchObj = re.match(r'(.*)../Config/(.*).cfg(.*)', line, re.M|re.I) 
    if matchObj: 
     print "Search : ", matchObj.group(2) 

#now replace searched expression to another name - so one more time find and replace - another way - not working - file after run this code is empty?!!! 
for line in fileinput.FileInput(myfile, inplace=1):  
    matchObj = re.match(r'(.*)../Config/(.*).cfg(.*)', line, re.M|re.I) 
    if matchObj: 
     line = line.replace("Config","AnotherConfig") 

回答

0

docs

可選就地過濾:如果關鍵字參數就地= 1被傳遞到fileinput.input()或所述的FileInput構造函數,則文件被移動到備份文件並且標準輸出被定向到輸入文件(如果與備份文件同名的文件已經存在,它將被無提示地替換)。

你需要做的只是在循環的每一步打印line。此外,您需要在不添加換行符的情況下打印行,因此您可以使用sys模塊中的sys.stdout.write。其結果是:

import fileinput 
import re 
import sys 

... 
for line in fileinput.FileInput(myfile, inplace=1):  
    matchObj = re.match(r'(.*)../Config/(.*).cfg(.*)', line, re.M|re.I) 
    if matchObj: 
     line = line.replace("Config","AnotherConfig") 
    sys.stdout.write(line) 

新增: 此外,我認爲你需要更換config.cfgAnotherConfig.cfg。在這種情況下,你可以做這樣的事情:

import fileinput 
import re 
import sys 

myfile = "Tset.cpp" 

regx = re.compile(r'(.*?\.\./Config/)(.*?)(\.cfg.*?)') 

for line in fileinput.FileInput(myfile, inplace=1):  
    matchObj = regx.match(line, re.M|re.I) 
    if matchObj: 
     sys.stdout.write(regx.sub(r'\1AnotherConfig\3', line)) 
    else: 
     sys.stdout.write(line) 

你可以閱讀功能sub這裏:python docs

0

如果我理解你,你想在該行改變:

std::string l_dbConfigDataFileName = "../../Config/configDB.cfg"; 

只是文件名「configBD」一些其他的文件名和重寫文件。

首先,我會建議寫入一個新文件並更改文件名以防出現問題。而不是使用re.match使用re.sub,如果有匹配的話,它會返回修改過的行,如果沒有,它會返回未修改的行 - 只需將它寫入一個新文件。然後將文件名 - 舊文件更改爲.bck,將新文件更改爲舊文件名。

import re 
import os 

regex = re.compile(r'(../config/)(config.*)(.cfg)', re.IGNORECASE) 

oldF = 'find_config.cfg' 
nwF = 'n_find_config.cfg' 
bckF = 'find_confg.cfg.bck' 

with open (oldF, 'r') as f, open (nwF, 'w') as nf : 
    lns = f.readlines() 
    for ln in lns: 
     nln = re.sub(regex, r'\1new_config\3', ln) 
     nf.write (nln) 


os.rename (oldF, bckF) 
os.rename (nwF, oldF)