Python将字符串与几个正则表达式进行比

时间:2010-04-13 22:51:43

标签: python regex switch-statement

我对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做什么(或想想!)的方法是什么?

4 个答案:

答案 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"