在Python 3.6的re模块中使用re.finditer()函数和re.DOTALL标志的错误吗?

时间:2019-01-03 02:55:07

标签: python regex pattern-matching newline flags

使用Python 3.6时,在re.finditer()中使用re.DOTALL时,我得到的结果很奇怪。 我不知道这是否是预期的操作,或者我是否缺少某些内容或它是否有错误。

案例1

我尝试使用此版本的带有嵌入式换行符的字符串。

我希望返回2个匹配的值:m1 ='abc'和m2 ='de'

import re
result = re.finditer('.*', 'abc\n de', flags=0)
m1 = result.__next__()
#    <_sre.SRE_Match object; span=(0, 3), match='abc'>
m2 = result.__next__()
#    <_sre.SRE_Match object; span=(3, 3), match=''>
m3 = result.__next__()
#    <_sre.SRE_Match object; span=(4, 7), match=' de'>
m4 = result.__next__()
#    <_sre.SRE_Match object; span=(7, 7), match=''>

匹配值m2和m4有什么用?

案例2

我尝试使用re.DOTALL进行此操作,并且希望能重新获得一场比赛,m1 ='abc \ n de'

result = re.finditer('.*', 'abc\n de', flags=re.DOTALL)
m1 = result.__next__()
#     <_sre.SRE_Match object; span=(0, 7), match='abc\n de'>
m2 = result.__next__()
#     <_sre.SRE_Match object; span=(7, 7), match=''>

多余的比赛有什么用?如何使结果按预期工作?

我希望第一种情况返回...

m1 = 'abc'
m2 = ' de'

...和第二种情况返回

m1 = 'abc\n de'

,没什么。

1 个答案:

答案 0 :(得分:1)

您的模式是

.*

这意味着“匹配零个或多个字符”;允许零宽度匹配。

在第一种情况下,存在m2m4的原因是该模式在换行符处停止匹配,然后尝试从该位置(索引3)开始查找新的匹配项。没有字符匹配,但是模式仍然允许,因为它是.*,因此第一个匹配是

span=(0, 3)

第二场比赛有

span=(3, 3)

span=(7, 7)和您的m4代码中的DOTALL也发生了同样的事情。

听起来只有在至少有一个字符的情况下才需要匹配-用+而不是*重复:

re.finditer('.+', 'abc\n de')