2013-04-26 55 views

回答

3

您可以使用re.finditer,因为它返回一个迭代器而不是一次生成的所有值:

In [21]: strs="12345678" 

In [22]: it=re.finditer("\d",strs) 

In [23]: [next(it).group(0) for _ in xrange(4)] #returns only 4 mathces 
Out[23]: ['1', '2', '3', '4'] 

虽然这可能会引发StopIteration错误时的限制比匹配的数量更大。一个简单的解决方法是使用异常处理或使用itertools.isclice

In [26]: def limiter(strs,pattern,limit): 
    it=re.finditer(pattern,strs) 
    try: 
     for _ in xrange(limit): 
      yield next(it).group(0) 
    except StopIteration:   
     pass 
    ....:  

In [27]: list(limiter("12345","\d",3)) 
Out[27]: ['1', '2', '3'] 

In [28]: list(limiter("12345","\d",6)) 
Out[28]: ['1', '2', '3', '4', '5'] 

In [29]: list(limiter("12345","\d",10)) 
Out[29]: ['1', '2', '3', '4', '5'] 

帮助上re.finditer

In [24]: re.finditer? 
Type:  function 
String Form:<function finditer at 0xb74114c4> 
File:  /usr/lib/python2.7/re.py 
Definition: re.finditer(pattern, string, flags=0) 
Docstring: 
Return an iterator over all non-overlapping matches in the 
string. For each match, the iterator returns a match object. 

Empty matches are included in the result. 
+1

或'.groups()'当你有多个组时。顺便说一句,如果你没有“限制”匹配,这会中断 – jamylak 2013-04-26 11:57:00

+0

感谢你对这个详细的解释和限制器功能。 – nutship 2013-04-26 12:07:59

4

使用re.finditeritertools.islice

from itertools import islice 
import re 

limit = 2 

for x in islice(re.finditer(r'\d+', '1 2 33'), limit): 
    print(x.group()) 

作为一个功能:

def findall_limiter(pattern, string, flags=0): 
    return islice(re.finditer(pattern, string, flags), limit) 

例如。

for match in findall_limiter(r'\d+', '1 2 33', 2): 
    # do stuff 
+1

其实这是更好的方法,因为当你没有“限制”匹配时它不会中断 – jamylak 2013-04-26 11:59:15