无法使用Python中的re.sub和io.StringIO进行内联替换

时间:2013-09-17 12:00:48

标签: python regex stringio

我已经编写了这个方法来替换文本。它打印正确的文本,因为我希望它被替换,但它不会更新文件中的这些更改。我对Python很陌生,你能帮助我在哪里犯错吗?

def regFind(regx, sub_text, file_name):
  c_file = io.StringIO(file_name)
  for line in c_file:
    match = regx.search(line)
    if match:
      replaced_line = re.sub(regx, sub_text, line)
      line = replaced_line
      #print(line)
    yield line

    regx = re.compile(r'^MYTEXT')
    sub_text = 'NewText'
    a_file = open('file.txt').read()
    for line in regFind(regex, sub_text, a_file):
      print(line)

3 个答案:

答案 0 :(得分:1)

标准库中有一个模块可以“就地”编辑文件 - fileinput。实际上,它不会就地编辑文件,而是将输出写入临时文件,然后临时文件重命名为原始文件。这使得如果一切顺利,就好像文件已经就地编辑了一样。如果存在异常,或者在重命名步骤之前程序已停止,则原始文件保持不变。

import fileinput
import sys
import re

screen = sys.stdout
def regFind(regx, sub_text, filename):
    for line in fileinput.input([filename],
            inplace=True,
            backup='.bak'   # creates a backup of the original file
            ):
        match = regx.search(line)
        if match:
            line = regx.sub(sub_text, line)
        sys.stdout.write(line)
        yield line

# regex = re.compile(r'foo')    
for line in regFind(regex, sub_text, 'file.txt'):
    screen.write(line+'\n')

fileinput重定向sys.stdout以写入临时文件,而不是控制台。因此,为了打印到控制台,我将原始sys.stdout保存到变量screen并使用screen.write代替print

答案 1 :(得分:0)

您需要明确地将更改写入文件。例如,以写入模式('w')打开另一个文件并使用.write方法将数据放入磁盘:

def regFind(regx, sub_text, a_file):
  for line in a_file:
    match = regx.search(line)
    if match:
      replaced_line = re.sub(regx, sub_text, line)
      line = replaced_line
      #print(line)
    yield line

f = open('file.txt')
out = open('result.txt', 'w')
for line in regFind(regex, sub_text, f):
  out.write(line)

(我还删除了不必要的StringIO并停止使用.read()将整个文件加载到内存中

P.S。我写给另一个文件的原因是它更安全。可以在适当的位置更改文件。但如果不够小心,你可能会丢失数据。

答案 2 :(得分:0)

编辑您的代码无效,因为您不会将这些行写入文本文件。

此外,如果你想要替换文件中的文本,你需要复制文件的内容,在writemode中打开文件(清空整个文件),然后将修改后的内容写入文件:

def regFindAndReplace(regx, sub_text, fileName):
    textFile = open(fileName)
    fileContent = textFile.readlines()
    textFile.close()
    writeFile = open(fileName,'w')
    for line in fileContent:
        # strip removes newline character if line has one, you probably wont need it but it does not do harm either
        line = line.strip()
        match = regx.search(line)
        if match:
            replaced_line = re.sub(regx, sub_text, line)
            line = replaced_line
            #print(line)
        writeFile.write(line+'\n')
        #'\n' is way to create newline character because stripped line has it no longer
    writeFile.close()

f = 'MyFile.txt'
regFindAndReplace(regex, sub_text, f)