2011-02-10 5 views
23

Я запутался, возвращая несколько групп в Python. Мой RegEx это:Python RegEx несколько групп

lun_q = 'Lun:\s*(\d+\s?)*' 

И моя строка

s = '''Lun:      0 1 2 3 295 296 297 298'''` 

Я возвращаю подобранный объект, а затем хочу посмотреть на группах, но все это показывает, что это последний номер (258):

r.groups() 
(u'298',) 

Почему он не возвращает группы 0,1,2,3,4 и т. Д.?

+3

Я думаю, что вы непосредственно относятся к называется [Захват Повторные группы] (http://www.regular-expressions.info/captureall .html) - или по линиям, обращающимся к каждому совпадению в группе с количественным/повторным захватом. см. [этот аналогичный ответ] (http://stackoverflow.com/a/3537914/611007) для javascript. не знаю наверняка, но *** они, похоже, не поддерживаются в регулярном выражении python ***. см. [связанный запрос улучшения python] (http://bugs.python.org/issue7132) и [связанный вопрос] (http://stackoverflow.com/q/15908085/611007) – n611x007

ответ

20

В вашем регулярном выражении содержится только одна пара круглых скобок (одна группа захвата), поэтому вы получаете только одну группу в своем матче. Если вы используете оператор повторения в группе захвата (+ или *), группа получает «перезаписывается» каждый раз, когда группа повторяется, что означает, что только последнее совпадение захватывается.

В вашем примере здесь, вы, вероятно, лучше использовать .split(), в сочетании с регулярным выражением:

lun_q = 'Lun:\s*(\d+(?:\s+\d+)*)' 
s = '''Lun: 0 1 2 3 295 296 297 298''' 

r = re.search(lun_q, s) 

if r: 
    luns = r.group(1).split() 

    # optionally, also convert luns from strings to integers 
    luns = [int(lun) for lun in luns] 
+3

Выбор 're.match()' vs 're.split()' является нетривиальным решением – smci

2

Другим подходом будет использовать регулярное выражение, вы должны подтвердить свои данные, а затем использовать более специфическое регулярное выражение, которое предназначено для каждого элемента, который вы хотите извлечь, используя итератор соответствия.

import re 
s = '''Lun: 0 1 2 3 295 296 297 298''' 
lun_validate_regex = re.compile(r'Lun:\s*((\d+)(\s\d+)*)') 
match = lun_validate_regex.match(s) 
if match: 
    token_regex = re.compile(r"\d{1,3}") 
    match_iterator = token_regex.finditer(match.group(1)) 
    for token_match in match_iterator: 
     #do something brilliant 
+0

print re.findall ('\ d', s) –

6

Иногда его легче без регулярного выражения.

>>> s = '''Lun: 0 1 2 3 295 296 297 298''' 
>>> if "Lun: " in s: 
...  items = s.replace("Lun: ","").split() 
...  for n in items: 
...  if n.isdigit(): 
...   print n 
... 
0 
1 
2 
3 
295 
296 
297 
298 
1

Если вы ищете вывода, таких как 0,1,2,3,4 и т.д. самые простые ответ ниже.

печати re.findall ('\ d', s)

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