句点导致Python中的多行正则替换停止?
我有一个包含多行的字符串,想要替换一些内容,但不知道为什么不成功。奇怪的是,字符串中的一个句号让正则表达式无法匹配。
我的字符串是:
s = """
[some_previous_text]
<start>
one_period .
<end>
[some_text_after]
"""
我想要的结果是:
s = """
[some_previous_text]
foo
[some_text_after]
"""
我最开始尝试的方式,但什么都没匹配到:
>>> import re
>>> s = "<start>\none_period .\n<end>"
>>> print re.sub("<start>[^.]*<end>", "foo", s)
<start>
one_period .
<end>
不过,当我把句号去掉后,它就能正常工作了:
>>> import re
>>> s = "<start>\nno_period\n<end>"
>>> print re.sub("<start>[^.]*<end>", "foo", s)
foo
而且,当我在句号前加了一个 <end>
标签时,它匹配到了第一个 <end>
标签:
>>> import re
>>> s = "<start>\n<end>\none_period .\n<end>"
>>> print re.sub("<start>[^.]*<end>", "foo", s)
foo
one_period .
<end>
那么这是怎么回事呢?为什么句号会让 [^.]*
无法匹配呢?
编辑:
已解决
我错误地认为插入符号 ^
是用来匹配新行的。其实我需要的是一个 re.DOTALL 标志(正如 Amber 所说)。这是我现在使用的表达式:
>>> import re
>>> s = "<start>\none_period .\n<end>"
>>> print re.sub("<start>.*<end>", "foo", s, flags=re.DOTALL)
foo
2 个回答
1
这是因为 [^.]*
是一个否定字符类,它可以匹配任何字符,除了句点(.)。
你可能想要的是类似 <start>.*?<end>
的写法,再加上 re.S
这个修饰符,这样点号(.)就可以匹配换行符了。
re.sub("<start>.*?<end>", "foo", s, flags=re.S)
4
为什么不呢?[^.]
的意思是“所有不是 .
的字符”,所以它不会匹配句点。
也许你想用 .*
(表示任意数量的任意字符)来代替 [^.]*
?
如果你想匹配跨越多行的内容,可以使用 re.DOTALL
:
re.sub("<start>.*<end>", "foo", s, flags=re.DOTALL)