保留re.sub捕获

时间:2015-08-18 18:39:32

标签: python regex

我正在使用像这样的re.sub:

def some_func(text):
    text = my_regex.sub(lambda m: do_something(m), text)
    return text

有时我想单独保留my_regex正在捕获的内容。

要在一次通过中执行此操作,我可以想象do_something可以在将文本返回到sub之前更改global变量:

captures = []
def do_something(m):
    global captures
    captures = []
    if m.group(1):
         captures.append(m.group(1))
    return 'TEXT_TO_SUB_IN'

那么:

def some_func(text):
    text = my_regex.sub(lambda m: do_something(m), text)
    c = deepcopy(captures)

但这太可怕了。把这一切变成class并做类似的事情似乎也很糟糕。

这样做有更好的模式:对于subbing并且还在一次传递中返回捕获?

2 个答案:

答案 0 :(得分:1)

首先,两行

text = my_regex.sub(lambda m: do_something(m), text)

text = my_regex.sub(do_something, text)

具有相同的效果,因此无需引入lambda的复杂性。

其次,在代码中

global captures
captures = []
if m.group(1):
     captures.append(m.group(1))

你应该删除前两个语句。每次执行匹配时都不应将其设置为空,否则您将丢失先前匹配的结果,因为这意味着您只是变更列表而不是分配,您不需要global声明。

但考虑到功能的满分,这似乎是最有效的方法。

作为re.sub的第一个参数给出的函数返回的值被用作替换字符串,因此您没有机会返回可能被其他代码隐藏的其他值。 / p>

简而言之,一旦你消除了上面提到的缺陷,我认为这些缺陷归结为简单的经验,你实际上已经找到了解决问题的实际方法。

答案 1 :(得分:1)

您可以使用闭包代替global

def do_whatever():
    def sub(text):
        captured.append(text)
        return "new"

    captured = []
    result = re.sub(r".*", sub, "test test")
    print captured

    captured = []
    result = re.sub(r".*", sub, "foo bar")
    print captured