这个 Python 正则表达式匹配什么?
.*?[^\\]\n
我很困惑为什么 和.
都跟在*
后面?
。
*
意思是“尽可能多地匹配前一个元素(零次或多次)”。
*?
意思是“尽可能少地匹配前一个元素(零次或多次)”。
其他答案已经解决了这个问题,但是他们没有提出的是它如何更改正则表达式,如果re.DOTALL
提供了标志,它会产生巨大的差异,因为.
将匹配启用该标志的换行符。所以.*[^\\]\n
会从字符串的开头一直匹配到最后一个没有反斜杠的换行符(所以会有几行匹配)。
如果re.DOTALL
未提供标志,则差异更加微妙,[^\\]
将匹配反斜杠以外的所有内容,包括换行符。考虑以下示例:
>>> import re
>>> s = "foo\n\nbar"
>>> re.findall(r'.*?[^\\]\n', s)
['foo\n']
>>> re.findall(r'.*[^\\]\n', s)
['foo\n\n']
所以这个正则表达式的目的是找到不以反斜杠结尾的非空行,但是如果你使用.*
而不是.*?
你将匹配一个额外的\n
,如果你在非空行后面有一个空行。
发生这种情况是因为.*?
将只匹配fo
,[^\\]
将匹配第二个o
,以及\n
第一行末尾的匹配项。然而,.*
将匹配foo
,[^\\]
将匹配\n
结束第一行,下一个\n
将匹配,因为第二行是空白的。
.
表示通配符。它可以匹配除 a 之外的任何内容\n
,除非使用了适当的标志。
*
表示你可以在它前面有 0 个或更多的东西。
?
表示前面的量词是惰性的。它将在找到第一个匹配项后停止搜索。
打开Python re 模块文档,并搜索*?
,我们发现:
*?
,+?
,??
:,
*
,+
和?
限定词都是贪婪的;它们匹配尽可能多的文本。有时这种行为是不希望的;如果 RE<.*>
与 匹配<H1>title</H1>
,它将匹配整个字符串,而不仅仅是<H1>
. 在限定符之后添加?
使其以非贪婪或最小方式执行匹配;将匹配尽可能少的字符。.*?
在前面的表达式中使用将仅匹配<H1>
。