2014-11-07 2 views
0

Мне нужно сделать re.match последовательно, и в случае совпадения мне нужен результат совпадения для выбора групп. Теперь я могу сделать следующее:Назначить и сравнить в python

r = re.match('cond1', l) 
if r: 
    # work with r.group() 
else: 
    r = re.match('cond2', l) 
    if r: 
     # work with r.group() 
    else: 
     r = re.match('cond3', l) 
     if r: 
      # work with r.group() 

и т. Д. Но как я могу сделать лучше? Я вижу, что это не возможно выполнить задание, если так:

if r = re.match('cond1', l): 
    # work with r.group() 
elif r = re.match('cond2', l): 
    # work with r.group() 
elif r = re.match('cond3', l) 
    # work with r.group() 
+0

Нет, это невозможно. – thebjorn

+0

Да, я это понял, но как лучше справляться с такой проблемой? – user3479125

+0

Обычно, когда вы пытаетесь объединить 3 или более вещи вместе, лучше спросить, как соединить любое произвольное количество вещей вместе. Обычно это означает цикл (или неявный цикл, например, в вызове 'map', или рекурсивная функция). – abarnert

ответ

3

Вы можете использовать понимание:

r, cond = next((m,c) for (m,c) in ((re.match(cond, line), cond) for cond in ('cond1', 'cond2', 'cond3')) if m) 

if cond=='cond1': 
    # work with r.group() for cond1 
elif cond=='cond2': 
    # work with r.group() for cond2 

Или, если это выглядит слишком аркан, петля:

for cond in ('cond1', 'cond2', 'cond3'): 
    r = re.match(cond, line) 
    if r: 
     break 

if not r: 
    # no match 
elif cond=='cond1': 
    # work with r.group() for cond1 
elif cond=='cond2': 
    # work with r.group() for cond2 
1

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

def first_match(haystack): 
    r = re.match('cond1', haystack) 
    if r: 
     # work with r.group() 
     return 
    r = re.match('cond2', l) 
    if r: 
     # work with r.group() 
     return 
    r = re.match('cond3', l) 
    if r: 
     # work with r.group() 

Все else бит и отступы головной боли уходят.


Кроме того, в общем случае, когда вы спрашиваете, как цепь 3 или больше вещей вместе, правильный ответ, чтобы выяснить, как цепь произвольное количество вещей вместе, и просто сделать с N = 3. Обычно это цикл (или цикл, скрытый внутри функции, например map, или определение рекурсивной функции и т. Д.). Например:

def first_match(exprs, haystack): 
    for expr in exprs: 
     r = re.match(expr, haystack) 
     if r: 
      return r 

В этом случае, однако, что вы пытаетесь сделать, это на самом деле выполнимо. Может быть, не очень хорошая идея, но ... Регулярное выражение match объект всегда правдивый. И, конечно, ложь None. Итак:

r = re.match('cond1', l) or re.match('cond2', l) or re.match('cond3', l) 
if r: 
    # work with r.group(), which is the group for whichever matched 

Но обратите внимание, что если вы хотите использовать truthiness, вы можете сделать это в цикле тоже:

next(filter(bool, (re.match(cond, l) for cond in ('cond1', 'cond2', 'cond3')))) 

Наконец, вы уже используете регулярные выражения, так почему бы не использовать регулярные выражения?

r = re.match('cond[123]', l) 
if r: 
    # work with r.group() 
Смежные вопросы