如何删除start
和end
之间的行,包括匹配单词的行。
line1
line2
start
line3
line4
line5
line6
end
line7
line8
我期望的结果是: -
line1
line2
line7
line8
我尝试了以下代码,但似乎没有任何工作。
text = "line1\nline2\nstart\nline3\nline4\nline5\nline6\nend\nline7\nline8"
print re.sub(r'start(.*)end', '', text)
答案 0 :(得分:4)
您必须使用修饰符re.DOTALL
才能使(.*)
匹配换行符:
re.sub(r'start(.*)end', '', text, flags=re.DOTALL)
然后,我认为使用懒惰的(.*?)
更安全,以防你有类似的事情:
line1\nstart\nline2\nline3\nend\nline4\nline5\nstart\nline6\nend\nline7
没有(.*?)
的内容将删除从第一个start
到最后一个end
的所有内容,包括中间不在start
和end
之间的内容:< / p>
re.sub(r'start.*?end', '', text, flags=re.DOTALL)
最后,我删除了括号,因为这里实际上并不需要它们。
如果您要删除遗留下来的所有空白,请使用\s*
修剪它们:
re.sub(r'start.*?end\s*', '', text, flags=re.DOTALL)
答案 1 :(得分:1)
默认情况下,.
字符不匹配换行符。您需要通过设置re.DOTALL
flag。
>>> text = "line1\nline2\nstart\nline3\nline4\nline5\nline6\nend\nline7\nline8"
>>> print re.sub(r'start(.*)end', '', text, flags=re.DOTALL)
line1
line2
line7
line8
请注意,之间有一个空行;您还需要在 end
之后添加换行符:
>>> print re.sub(r'start(.*)end\n', '', text, flags=re.DOTALL)
line1
line2
line7
line8
作为.
的替代方案,您还可以同时使用两个相反的角色类:
>>> print re.sub(r'start([\s\S]*)end\n', '', text)
line1
line2
line7
line8
此处\s
和\S
一起捕获所有字符,包括换行符,但未设置DOTALL
标记。
你可能想让你的比赛变得非贪婪。如果您的输入中有两个组start
和end
行,则.*
将匹配第一个start
所有文本到最后end
的方式:
>>> text = 'line1\nstart\nline2\nend\nline3\nstart\nline4\nend\nline5'
>>> print text
line1
start
line2
end
line3
start
line4
end
line5
>>> print re.sub(r'start(.*)end\n', '', text, flags=re.DOTALL)
line1
line5
注意line3
也是如何消失的。通过添加问号来改变*
,使其变得非贪婪:
>>> print re.sub(r'start(.*?)end\n', '', text, flags=re.DOTALL)
line1
line3
line5