Python3 - 多行匹配模式

2018-12-19  本文已影响40人  惑也

问题

使用正则表达式匹配一大块文本时,需要跨多行去匹配。

解决方案

当用点(.)去匹配任意字符的时候,容易忘记点(.)不能匹配换行符的事实。 比如:

import re

recom = re.compile('/\*(.*?)\*/')   # 匹配/* 和 */之间的字符串,*?表示非贪婪模式匹配

text1 = '/* this is a comment */'
print(recom.findall(text1))
[' this is a comment ']

text2 = '''/* this is a 
        multiline comment */
        '''
print(recom.findall(text2))
[]

修改模式字符串,增加对换行的支持。比如:

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

(?:.|\n) 指定了一个非捕获组,与模式匹配,但不保存匹配项。也就是它定义了一个仅仅用来做匹配,而不能通过单独捕获或者编号的组。

讨论

re.compile() 函数接受一个参数 re.DOTALL ,可以让正则表达式中的点(.)匹配包括换行符在内的任意字符。比如:

rc = re.compile(r'/\*(.*?)\*/', re.DOTALL)
print(rc.findall(text2))
[' this is a \nmultiline comment ']

对于简单的匹配情况,推荐使用 re.DOTALL 标记参数的方式实现点(.)匹配包括换行符,但是如果模式非常复杂或者是为了构造字符串令牌而将多个模式合并起来, 使用这个标记参数可能会出现问题,建议定义自己的正则表达式模式,这样它可以在不需要额外的标记参数下实现匹配。

上一篇 下一篇

猜你喜欢

热点阅读