删除Python中的多行
我有一个文件如下所示:删除Python中的多行,python,Python,我有一个文件如下所示: <VirtualHost *:80> ServerName Url1 DocumentRoot Url1Dir </VirtualHost> <VirtualHost *:80> ServerName Url2 DocumentRoot Url2Dir </VirtualHost> <VirtualHost *:80> ServerName REMOVE </Vi
<VirtualHost *:80>
ServerName Url1
DocumentRoot Url1Dir
</VirtualHost>
<VirtualHost *:80>
ServerName Url2
DocumentRoot Url2Dir
</VirtualHost>
<VirtualHost *:80>
ServerName REMOVE
</VirtualHost>
<VirtualHost *:80>
ServerName Url3
DocumentRoot Url3Dir
</VirtualHost>
服务器名Url1
文档根Url1Dir
服务器名Url2
文档根Url2Dir
服务器名删除
服务器名Url3
文档根Url3Dir
我想删除这段代码的地方(它不会改变):
服务器名删除
我试图通过使用下面的代码来找到整个代码,但它似乎不起作用
with open("out.txt", "wt") as fout:
with open("in.txt", "rt") as fin:
for line in fin:
fout.write(line.replace("<VirtualHost *:80>\n ServerName REMOVE\n</VirtualHost>\n", ""))
以open(“out.txt”、“wt”)作为fout的:
打开(“in.txt”、“rt”)作为fin:
对于fin中的行:
fout.write(line.replace(“\n ServerName REMOVE\n\n”,”))
我曾试图找到解决我问题的办法,但结果却是空手而归,所以我非常感谢你的帮助
在你否决投票之前,我很想听听原因。最快的方法是将整个文件读入一个字符串,执行替换,然后将该字符串写入所需的文件。例如:
#!/usr/bin/python
with open('in.txt', 'r') as f:
text = f.read()
text = text.replace("<VirtualHost *:80>\n ServerName REMOVE\n</VirtualHost>\n\n", '')
with open('out.txt', 'w') as f:
f.write(text)
#/usr/bin/python
以open('in.txt','r')作为f:
text=f.read()
text=text.replace(“\n ServerName REMOVE\n\n”,”)
以open('out.txt','w')作为f:
f、 书写(文本)
这是有限自动机解决方案,可以在以后的开发过程中轻松修改。一开始可能看起来很复杂,但请注意,您可以独立地查看每个状态值的代码。您可以在纸上绘制图形(节点作为圆,箭头作为定向边),以获得所做操作的概述
status = 0 # init -- waiting for the VirtualHost section
lst = [] # lines of the VirtualHost section
with open("in.txt") as fin, open("out.txt", "w") as fout:
for line in fin:
#-----------------------------------------------------------
# Waiting for the VirtualHost section, copying.
if status == 0:
if line.startswith("<VirtualHost"):
# The section was found. Postpone the output.
lst = [ line ] # first line of the section
status = 1
else:
# Copy the line to the output.
fout.write(line)
#-----------------------------------------------------------
# Waiting for the end of the section, collecting.
elif status == 1:
if line.startswith("</VirtualHost"):
# The end of the section found, and the section
# should not be ignored. Write it to the output.
lst.append(line) # collect the line
fout.write(''.join(lst)) # write the section
status = 0 # change the status to "outside the section"
lst = [] # not neccessary but less error prone for future modifications
else:
lst.append(line) # collect the line
if 'ServerName REMOVE' in line: # Should this section to be ignored?
status = 2 # special status for ignoring this section
lst = [] # not neccessary
#-----------------------------------------------------------
# Waiting for the end of the section that should be ignored.
elif status == 2:
if line.startswith("</VirtualHost"):
# The end of the section found, but the section should be ignored.
status = 0 # outside the section
lst = [] # not neccessary
status=0#init——等待VirtualHost部分
lst=[]#虚拟主机部分的行
以open(“in.txt”)作为fin,open(“out.txt”,“w”)作为fout:
对于fin中的行:
#-----------------------------------------------------------
#正在等待VirtualHost部分,正在复制。
如果状态==0:
如果line.startswith(“以上的答案是一种务实的方法,那么它首先是脆弱的,不灵活的。
以下是一些不那么脆弱的东西:
import re
def remove_entry(servername, filename):
"""Parse file , look for entry pattern and return new content
:param str servername: The server name to look for
:param str filename: The file path to parse content
:return: The new file content excluding removed entry
:rtype: str
"""
with open(filename) as f:
lines = f.readlines()
starttag_line = None
PATTERN_FOUND = False
for line, content in enumerate(lines):
if '<VirtualHost ' in content:
starttag_line = line
# look for entry
if re.search(r'ServerName\s+' + servername, content, re.I):
PATTERN_FOUND = True
# next vhost end tag and remove vhost entry
if PATTERN_FOUND and '</VirtualHost>' in content:
del lines[starttag_line:line + 1]
return "".join(lines)
filename = '/tmp/file.conf'
# new file content
print remove_entry('remove', filename)
重新导入
def remove_条目(服务器名、文件名):
“”“解析文件,查找条目模式并返回新内容
:param str servername:要查找的服务器名称
:param str filename:解析内容的文件路径
:return:不包括已删除项的新文件内容
:rtype:str
"""
打开(文件名)为f时:
行=f.读行()
starttag_线=无
找到的模式=错误
对于行,枚举中的内容(行):
如果“你不应该做fin.read()
或其他什么?fin中的行的是否像这样工作?如果是这样,您将逐行读取文件,因此替换3行将不起作用…一次读取几行:这看起来像一个XML文件,因此可能您可以使用XML解析器来完成该任务。例如,或者。正如卡尔森所写的,您可能应该将问题更新为expres这就是目标。更好的解决方案可能与您现在尝试的略有不同。您甚至可以使用内置模块xml.etree。ElementTree@pepr是的,但我现在的代码也将用于我将来要做的东西,它不是XML,所以它不受删除XML的限制。我实际上在使用这个脚本tead,因为它还可以删除DocumentRoot行,只需进行一些编辑。谢谢!:)当添加更多的elif status==x:
时,最好同时添加else:
,以便在未实现新状态的情况下进行诊断。我的经验是,最好不要对状态值重新编号,只需添加一个新值。有限自动机可能需要一些特殊情况,如意外的文件结尾或因此,我选择可见的状态号,如555
。
import re
def remove_entry(servername, filename):
"""Parse file , look for entry pattern and return new content
:param str servername: The server name to look for
:param str filename: The file path to parse content
:return: The new file content excluding removed entry
:rtype: str
"""
with open(filename) as f:
lines = f.readlines()
starttag_line = None
PATTERN_FOUND = False
for line, content in enumerate(lines):
if '<VirtualHost ' in content:
starttag_line = line
# look for entry
if re.search(r'ServerName\s+' + servername, content, re.I):
PATTERN_FOUND = True
# next vhost end tag and remove vhost entry
if PATTERN_FOUND and '</VirtualHost>' in content:
del lines[starttag_line:line + 1]
return "".join(lines)
filename = '/tmp/file.conf'
# new file content
print remove_entry('remove', filename)