需要帮助重构我的Python脚本

3

我有一个处理文件的python脚本,逐行处理文件,如果匹配到正则表达式,就调用函数进行处理。

我的问题是,有没有更好的方法来重构我的脚本。虽然目前这个脚本可以运行,但是随着我不断添加更多的正则表达式,需要将缩进保持在编辑器的右侧。

感谢任何想法和建议。 现在我的代码看起来像这样:

for line in fi.readlines():
result= reg1.match(line)
if result: handleReg1(result)
else: result = reg2.match(line)
if result: handleReg2(result) else: result = reg3.match(line)
if result: handleReg3(result) else: result = reg4.match(line)
if result: handleReg4(result) else: result = reg5.match(line)
if result: handleReg5(result)
3个回答

12

我会转而使用一种将正则表达式映射到函数的数据结构。类似于:

map = { reg1: handleReg1, reg2: handleReg2, etc }

然后您只需要循环遍历它们:

for reg, handler in map.items():
    result = reg.match(line)
    if result:
       handler(result)
       break
如果你需要按照特定的顺序进行匹配,你需要使用列表而不是字典,但原理是相同的。

这也是我推荐的方法。正如Sam提到的,如果你需要特定的顺序,你可以使用列表 - 可能是像handlers = [(reg1, handleReg1), (reg2, handleReg2), ...]这样的写法。然后你的for循环将会是这样:for (reg,handler) in handlers: - Amber
1
你肯定想要一个列表而不是字典。这里没有键查找 - 它只是正则表达式和函数之间的关联。元组列表会很好。 - hughdbrown

1
这是一个微不足道的例子:
handlers = { reg1 : handleReg1, ... }

for line in fi.readlines():
    for h in handlers:
        x = h.match(line)
        if x:
            handlers[h](x)

如果有一行代码可以匹配多个正则表达式,那么这段代码将与您粘贴的代码不同:它将调用多个处理程序。添加“break”是没有帮助的,因为正则表达式将按不同的顺序尝试,所以最终会调用错误的处理程序。因此,如果是这种情况,您应该遍历列表:
handlers = [ (reg1, handleReg1), (reg2, handleReg2), ... ]

for line in fi.readlines():
    for reg, handler in handlers:
        x = reg.match(line)
        if x:
            handler(x)
            break

这并不相同;你的方式可能会调用多个处理程序;他的方式最多只调用一个。 - balpha
以上版本也不完全相同,因为它可能会尝试与 reg1、reg2 等不同顺序的正则表达式匹配。 - ilya n.

0
一个可能适用于您的替代方法是将所有正则表达式组合成一个巨大的正则表达式,并使用m.group()来检测哪个匹配。我的直觉是这应该会更快,但我还没有测试过。
>>> reg = re.compile('(cat)|(dog)|(apple)')
>>> m = reg.search('we like dogs')
>>> print m.group()
dog
>>> print m.groups()
(None, 'dog', None)

如果你要测试的正则表达式本身很复杂或使用了匹配组,那么这就变得复杂了。


非常快速,对抗使用匹配组的复杂内部正则表达式的解决方法是在它们周围使用命名组(在“命名空间”中,例如带有前缀,与内部正则表达式可能使用的任何命名组不相交)。 - Alex Martelli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接