繁体   English   中英

为什么 re.findall() 给我的结果与 Python 中的 re.finditer() 不同?

[英]Why does re.findall() give me different results than re.finditer() in Python?

我写了这个正则表达式:

p = re.compile(r'''
\[\[            #the first [[
[^:]*?          #no :s are allowed
.*?             #a bunch of chars
(
\|              #either go until a |
|\]\]           #or the last ]]
)
                ''', re.VERBOSE)

我想使用re.findall来获取某个字符串的所有匹配部分。 我写了一些测试代码,但它给了我奇怪的结果。

这段代码

g = p.finditer('   [[Imae|Lol]]     [[sdfef]]')
print g
for elem in g:
    print elem.span()
    print elem.group()

给我这个 output:

(3, 10)
[[Imae|
(20, 29)
[[sdfef]] 

完全有道理吗? 但是当我这样做时:

h = p.findall('   [[Imae|Lol]]     [[sdfef]]')
for elem in h:
    print elem

output 是这样的:

|
]]  

为什么 findall() 打印出的结果与 finditer 不一样?

Findall 返回匹配组的列表。 正则表达式中的括号定义了 findall 认为您想要的组,但您不想要组。 (?:...)是一个非捕获括号。 将您的正则表达式更改为:

'''
\[\[            #the first [[
[^:]*?          #no :s are allowed
.*?             #a bunch of chars
(?:             #non-capturing group
\|              #either go until a |
|\]\]           #or the last ]]
)
                '''

当你给re.findall()一个带有组(括号表达式)的正则表达式时,它会返回匹配的 在这里,您只有一个组,它是 | 或 ]] 结尾。 另一方面,在您使用 re.finditer() 的代码中,您没有特别要求任何组,因此它为您提供了整个字符串。

你可以让 re.findall() 做你想做的事,方法是在整个正则表达式周围加上括号 - 或者只是在你实际尝试提取的部分周围。 假设您正在尝试解析 wiki 链接,那将是第 4 行中的“一堆字符”。例如,

p = re.compile(r'''
\[\[            #the first [[
[^:]*?          #no :s are allowed
(.*?)           #a bunch of chars
(
\|              #either go until a |
|\]\]           #or the last ]]
)
                ''', re.VERBOSE)

p.findall('   [[Imae|Lol]]     [[sdfef]]')

返回:

[('Imae', '|'), ('sdfef', ']]')]

我认为findall()文档的关键是:

如果模式中存在一个或多个组,则返回组列表; 如果模式有多个组,这将是一个元组列表。

您的正则表达式在 pipe 或关闭 ]] 周围有一个组:

(
\|              #either go until a |
|\]\]           #or the last ]]
)

finditer()似乎没有任何这样的子句。

他们不返回相同的东西。 文档中的一些片段:

findall返回一个字符串列表。 如果模式中存在一个或多个组,则返回组列表; 如果模式有多个组,这将是一个元组列表。

finditer返回一个产生 MatchObject 实例的迭代器。

从 python 文档:

返回字符串中模式的所有非重叠匹配,作为字符串列表。 从左到右扫描字符串,并按找到的顺序返回匹配项。 如果模式中存在一个或多个组,则返回组列表; 如果模式有多个组,这将是一个元组列表。 空匹配包含在结果中,除非它们触及另一个匹配的开始。

请注意,它表示如果存在组,则将返回组匹配列表。 您在正则表达式末尾拥有的捕获组是匹配的,因此仅返回每个匹配中捕获的组部分。 当您使用 finditer 时,此信息只是 MatchObject object 中的另一个字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM