我对Perl和Ruby非常有经验,但对Python不熟悉所以我希望有人能告诉我Pythonic完成以下任务的方法。我想比较几行与多个正则表达式并检索匹配组。在Ruby中,它将是这样的:
# Revised to show variance in regex and related action.
data, foo, bar = [], nil, nil
input_lines.each do |line|
if line =~ /Foo(\d+)/
foo = $1.to_i
elsif line =~ /Bar=(.*)$/
bar = $1
elsif bar
data.push(line.to_f)
end
end
我在Python中的尝试变得非常难看,因为匹配组是从正则表达式上的匹配/搜索调用返回的,而Python在条件或switch语句中没有赋值。关于这个问题,Pythonic做什么(或想想!)的方法是什么?
答案 0 :(得分:1)
像这样,但更漂亮:
regexs = [re.compile('...'), ...]
for regex in regexes:
m = regex.match(s)
if m:
print m.groups()
break
else:
print 'No match'
答案 1 :(得分:1)
有几种方法可以在Python中“动态绑定名称”,例如我的旧recipe用于“分配和测试”;在这种情况下,我可能会选择另一种方式(假设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
当然,可以调整许多次要细节(例如,我只选择了(.*)
而不是(.*?)
作为匹配组 - 它们等同于紧随其后{{1}所以我选择了较短的形式;-) - 你可以预编译RE,使事物的因素与$
元组不同(例如,用RE模式索引的dict)等等。
但我认为,实质性的想法是使结构数据驱动,并使用子表达式pats_mark
将匹配对象绑定到动态名称,单个项目上的“循环” list(genexps仅通过循环绑定名称,而不是通过赋值绑定 - 有些人认为使用genexps规范的这一部分是“棘手的”,但我认为这是一个完全可以接受的Python习语,特别是因为它是在当时正在设计listcomps,genexps'“祖先”的时候再考虑过。)
答案 2 :(得分:0)
Paul McGuire's solution使用执行匹配的中间类REMatcher
,存储匹配组,并返回成功/失败的布尔值,以便为此目的生成最易读的代码。
答案 3 :(得分:-1)
你的正则表达式只需要在第3个字符之后的任何内容。
for line in open("file"):
if line.startswith("A:"):
print "FOO #{"+line[2:]+"}"
elif line.startswith("B:"):
print "BAR #{"+line[2:]+"}"
else:
print "No match"