2.8 多行匹�模�¶

问题¶

你正在试�使用正则表达�去匹�一大�的文本,而你需�跨越多行去匹�。

解决方案¶

这个问题很典型的出现在当你用点(.)去匹�任�字符的时候,忘记了点(.)�能匹��行符的事实。 比如,�设你想试�去匹�C语言分割的注释:

>>> comment = re.compile(r'/\*(.*?)\*/')
>>> text1 = '/* this is a comment */'
>>> text2 = '''/* this is a
... multiline comment */
... '''
>>>
>>> comment.findall(text1)
[' this is a comment ']
>>> comment.findall(text2)
[]
>>>

为了修正这个问题,你�以修改模�字符串,增加对�行的支�。比如:

>>> comment = re.compile(r'/\*((?:.|\n)*?)\*/')
>>> comment.findall(text2)
[' this is a\n multiline comment ']
>>>

在这个模�中, (?:.|\n) 指定了一个��获组 (也就是它定义了一个仅仅用��匹�,而�能通过�独�获或者编�的组)。

讨论¶

re.compile() 函数接�一个标志�数� re.DOTALL ,在这里�常有用。 它�以让正则表达�中的点(.)匹�包括�行符在内的任�字符。比如:

>>> comment = re.compile(r'/\*(.*?)\*/', re.DOTALL)
>>> comment.findall(text2)
[' this is a\n multiline comment ']

对于简�的情况使用 re.DOTALL 标记�数工作的很好, 但是如果模��常��或者是为了构造字符串令牌而将多个模��并起�(2.18节有详细�述), 这时候使用这个标记�数就�能出现一些问题。 如果让你选择的�,最好还是定义自己的正则表达�模�,这样它�以在�需��外的标记�数下也能工作的很好。