1

如何删除这些匹配单词之间的行startend包括这些行。

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)
4

2 回答 2

4

您将不得不使用修饰符re.DOTALL来制作(.*)匹配换行符:

re.sub(r'start(.*)end', '',  text, flags=re.DOTALL)

然后,我认为使用 lazy 会更安全,(.*?)以防万一您遇到以下情况:

line1\nstart\nline2\nline3\nend\nline4\nline5\nstart\nline6\nend\nline7

没有(.*?)将删除从第一个start到最后一个的所有内容,end包括不在中间startend中间的部分:

re.sub(r'start.*?end', '',  text, flags=re.DOTALL)

最后,我删除了括号,因为这里实际上不需要它们。

如果要删除所有留下的空白,请使用\s*修剪它们:

re.sub(r'start.*?end\s*', '',  text, flags=re.DOTALL)
于 2013-10-05T12:27:39.010 回答
1

默认情况下,该.字符不匹配换行符。您需要通过设置re.DOTALL标志来启用它。

>>> 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标志。

你可能想让你的匹配不贪心。如果您的输入中有两组startend,那么.*将匹配从第一个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
于 2013-10-05T12:24:58.033 回答