首先介绍一下背景:是的,我是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)
我也看过很多使用re
,replace
等的例子,但似乎与我需要的东西没什么关系。无论如何,现在我只是在同一目录中的一个文件上尝试它,但是当我在我的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文件中,我使用相同的注释标签,你得到了图片......
有什么建议吗?
答案 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)
另请注意,变量名file1
和file2
在这里有点误导,因为它们不是类似文件的对象,而是字符串。
答案 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文件测试了我的代码并确信它有效。我无法保证结果,特别是对于嵌套目录。祝你好运。