2013-04-26 6 views
1

Есть ли эквивалент регулярного выражения аргумента BeautifulSoup limit=X для метода findall? Я имею в виду, как найти первые X слов, о которых идет речь, а затем нарушить выполнение кода? спасибоКак ограничить метод findall() regex

+3

использование 're.finditer'. –

ответ

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()' для тех случаев, когда у вас несколько групп. Btw это ломается, если у вас нет совпадений 'limit' – jamylak

+0

Благодарим вас за подробное объяснение и функцию' limiter'. – nutship

4

Использование re.finditer и itertools.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

На самом деле это лучший способ, так как он не сломается, когда у вас нет совпадений 'limit' – jamylak

Смежные вопросы