使用python替换一个文件中的一段文本与另一个文本

时间:2013-04-22 17:34:13

标签: python

首先介绍一下背景:是的,我是python的新手,但我喜欢涉猎和学习。

目标是这样的:我在这里有一个内部网站点工作,他们让我们在静态服务器上,不允许服务器端脚本,这意味着没有PHP。因此,当我添加新页面时,我必须使用新链接更新每个freakin页面的菜单。幸运的是,我在我的计算机上安装了一个名为ArcGIS的应用程序,并且安装了python。所以我认为将一个脚本放在一起会读取一个名为“menu.txt”的文件,然后在我的目录(和子目录)中递归搜索带有“.html”的文件并在一些注释之间替换所有文本会很好标记,如<!--begin menu--><!--end menu-->,以及“menu.txt”中的文字

所以我开始寻找并找到了这段代码:

with open('menu.txt', 'r') as f:
    # read entire file into file1
    # ASSUMING 'file1.txt' is relatively small...
    file1 = f.read()

with open('test.html', 'r') as f:
    # ASSUMING 'file2.txt' is relatively small...
    file2 = f.read()    # read file into file2

# index() will raise an error if not found...
f1_start = file1.index('<!--123-->')
f1_end = file1.index('<!--321-->', f1_start)     # look for '//end' after '//start'

f2_start = file2.index('<!--123-->')
f2_end = file2.index('<!--321-->', f2_start)

# replace file2 lines with proper file1 lines
file2[f2_start:f2_end] = file1[f1_start:f1_end]

with open('test.html', 'w') as f:
    f.write(file2)

我也看过很多使用rereplace等的例子,但似乎与我需要的东西没什么关系。无论如何,现在我只是在同一目录中的一个文件上尝试它,但是当我在我的linux机器或windows python shell上运行时,我得到:

Traceback (most recent call last):
  File "P:\webpages\filereplace.py", line 18, in <module>
    file2[f2_start:f2_end] = file1[f1_start:f1_end]
TypeError: 'str' object does not support item assignment

我认为问题可能是with open部分,但我不知道。

在这种情况下,menu.txt的内容基本上是一个开始的评论标记<!--123-->,然后是所有<div id=menu>blah blah blah</div>,然后是结束评论标记<!--321-->。在我的html文件中,我使用相同的注释标签,你得到了图片......

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您正在尝试就地修改字符串。这在python中是不可能的,因为字符串是不可变的。

要实现您想要的效果,您需要从现有两个字符串的部分创建一个新字符串:

# replace file2 lines with proper file1 lines
new_f = file2[:f2_start] + file1[f1_start:f1_end] + file2[f2_end:]

之后,将内容写入文件,如下所示:

with open('test.html', 'w') as f:
    f.write(new_f)

另请注意,变量名file1file2在这里有点误导,因为它们不是类似文件的对象,而是字符串。

答案 1 :(得分:0)

大多数情况下,在处理文件的就地编辑时,我转向fileinput模块:

import os
import fileinput

if __name__ == '__main__':
    # Menu should not have any marker, just pure contents
    with open('menu.txt') as f:
        menu_contents = f.read()

    # Initialize a few items
    start_marker = '<!--123-->'
    end_marker   = '<!--321-->'
    file_list = ['index.html', 'foo.html']
    found_old_contents = False

    # Loop to replace text in place
    for line in fileinput.input(file_list, inplace=True):
        line = line.rstrip()

        if line == start_marker:
            found_old_contents = True
            print line
            print menu_contents
        elif line == end_marker:
            found_old_contents = False

        if not found_old_contents:
            print line

讨论

这里的关键是函数fileinput.input(file_list, inplace=True),它接受​​一个文件名列表,逐行迭代它们,然后写回print出来的文件。

您需要通过file_list或其他一些方法提供文件列表(例如os.walk())。

我已经针对两个.html文件测试了我的代码并确信它有效。我无法保证结果,特别是对于嵌套目录。祝你好运。