Есть несколько способов «связать имя на лету» в Python, например мой старый рецепт для «назначить и проверить»; в этом случае я бы, вероятно, выбрал другой такой путь (предполагая, что Python 2.6 требует небольших изменений, если вы работаете со старой версией Python), что-то вроде:
import re
pats_marks = (r'^A:(.*)$', 'FOO'), (r'^B:(.*)$', 'BAR')
for line in lines:
mo, m = next(((mo, m) for p, m in pats_mark for mo in [re.match(p, line)] if mo),
(None, None))
if mo: print '%s: %s' % (m, mo.group(1))
else: print 'NO MATCH: %s' % line
Конечно, можно изменить многие второстепенные детали (например, я просто выбрал (.*)
вместо (.*?)
в качестве соответствующей группы - они эквивалентны сразу после $
, поэтому я выбрал более короткую) form ;-) - вы могли бы предварительно скомпилировать RE, выделить вещи иначе, чем кортеж pats_mark
(например, с помощью dict, проиндексированного шаблонами RE) и т. д.
Но существенные идеи, я думаю, состоят в том, чтобы сделать структуру управляемой данными и связать объект сопоставления с именем на лету с помощью подвыражения for mo in [re.match(p, line)]
, «цикла» над списком из одного элемента ( genexps связывает имена только по циклу, а не по присваиванию - некоторые считают использование этой части спецификаций genexps «хитрым», но я считаю это вполне приемлемой идиомой Python, особенно, поскольку она была рассмотрена в то время, когда списочные списки, в некотором смысле, создавались "предками" genexps).