2011-05-27 104 views
5

我写了这样的正则表达式:为什么re.findall()给我的结果不同于Python中的re.finditer()?

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() 

给了我这样的输出:

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

权非常有意义?但是,当我这样做:

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

输出是这样的:

| 
]] 

为什么不是的findAll()打印出相同的结果finditer?

回答

7

Findall返回匹配组的列表。你的正则表达式中的缺陷定义了一个你认为你想要的组,但你不需要组。 (?:...)是一个没有捕获palenthesis。您正则表达式更改为:

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

这个问题解决了!我忘记了一点关于findall ...谢谢! – 2011-05-27 21:20:35

1

我觉得从findall() documentation键位是这样的:

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

你的正则表达式具有在管道周围的一组或关闭]这里:

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

finditer()不会出现任何这样的条款。

+0

有帮助。谢谢。 :) – 2011-05-27 21:20:53

1

他们不会返回相同的东西。来自docs的某些片段:

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

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

0

从Python文档:

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

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

3

当你给re.findall()一个正则表达式的组合(括号表达式)时,它返回匹配的。在这里,你只有一个组,而且是|或]]结尾。另一方面,在你使用re.finditer()的代码中,你并没有特别要求组,所以它会给你整个字符串。

您可以通过在整个正则表达式中放置圆括号来实现自己想要的功能 - 或者只是在实际尝试提取的部分的周围。假设你试图解析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', ']]')] 
+0

哇。一切都很有意义。搞清楚我要做什么。 – 2011-05-27 21:36:11

相关问题