findall()和使用for循环与迭代器查找模式匹配之间的区别是什么

时间:2012-02-01 19:42:01

标签: python regex

我用它来计算文本中的句子数量:

fileObj = codecs.open( "someText.txt", "r", "utf-8" )
shortText = fileObj.read()

pat = '[.]'

for match in re.finditer(pat, shortText, re.UNICODE):
    nSentences = nSentences+1

有人告诉我这更好:

result = re.findall(pat, shortText)
nSentences = len(result)

有区别吗?他们不是做同样的事吗?

5 个答案:

答案 0 :(得分:4)

第二个可能会快一点,因为迭代完全用C语言完成。速度快多少?在我的测试中大约有15%(在'a'中匹配'a' * 16),尽管由于正则表达式变得更复杂并占用更大比例的运行时间,这个百分比会变小。但它会使用更多内存,因为它实际上会为你创建一个列表。但是假设你没有大量的比赛,那么太多就会有更多的记忆。

至于我更喜欢​​哪种,我有点像第二种简洁,特别是当合并为一个声明时:

nSentences = len(re.findall(pat, shortText))

答案 1 :(得分:2)

finditer 函数返回匹配对象迭代器

findall 函数返回匹配字符串列表

迭代器优于列表的优点是它们对内存友好(仅在需要时生成值)。

匹配对象优于字符串的优点是它们具有多种功能(为您提供分组,分组,开始,结束,跨度等)。

最佳选择取决于您的需求。如果您需要匹配字符串列表,那么 findall 就很棒。如果您需要匹配对象方法或需要节省内存,那么 finditer 就是您的选择。

希望这会有所帮助。祝你的项目好运: - )

答案 2 :(得分:1)

他们做了很多相同的事情。您的选择应取决于您的其他用法是否表明迭代器或列表会更好。

答案 3 :(得分:1)

finditerfindall之间的一个区别是前者返回正则表达式match objects而另一个则返回组列表,如果模式中存在一个或多个组;如果模式有多个组,这将是list of tuples

除此之外,一切都取决于您的使用情况。

答案 4 :(得分:1)

主要有两点不同:

1)findall()返回一个列表,而finditer()返回一个迭代器。如果您要处理大字符串(如文件),这可能会有很大的不同。

2)findall()返回str个对象,而finditer()返回Match个对象。我认为这是主要的区别。因此,根据您需要从匹配中获得的信息,您可以选择其中一个。这是一个小例子:

我们希望从字符串中获取所有数字:

>>> s = 'I have 921 apples, 53 oranges, 3 bananas and 1 lemon.'
# if you just need to find them, better use findall():
>>> re.findall('\d+', s)
['921', '53', '3', '1']
# but, if you need more than just that, use finditer():
>>> [(m.group(), m.start(), m.end()) for m in re.finditer('\d+', s)]
[('921', 7, 10), ('53', 19, 21), ('3', 31, 32), ('1', 45, 46)]