使用正则表达式查找文本并替换文件

时间:2014-02-14 11:29:27

标签: python file-io str-replace

我想在文件中找到带有正则表达式的文本,然后将其替换为另一个名称。我必须首先逐行读取文件,因为换句话说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()
//...

现在是将configDB名称替换为另一个名称的python代码。我必须通过正则表达式找到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")

2 个答案:

答案 0 :(得分:0)

来自docs

  

可选的就地过滤:如果将关键字参数inplace = 1传递给fileinput.input()或FileInput构造函数,则将文件移动到备份文件,并将标准输出定向到输入文件(如果已存在与备份文件同名的文件,则会以静默方式替换它。)

您需要做的只是在循环的每个步骤中打印line。此外,您需要在没有其他换行符的情况下打印行,因此您可以使用sys.stdout.write模块中的sys。结果:

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.cfg替换为AnotherConfig.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

答案 1 :(得分: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 )