如何在不使用单独的替换函数的情况下循环正则表达式匹配并进行替换?

How to loop over regex matches and do replacement, without using a separate replacement function?

我需要将每个模式替换为:{foo}FOO + 递增的数字,并且每个匹配项还需要 do_something_else(...)。示例:

'hell{o} this {is} a t{est}' => hellO1 this IS2 a tEST3

如何不使用替换函数,而只用循环匹配?我正在寻找类似的东西:

import re

def do_something_else(x, y):  # dummy function
    return None, None

def main(s):
    i = 0
    a, b = 0, 0
    for m in re.findall(r"{([^{}]+)}", s):  # loop over matches, can we
        i += 1                              # do the replacement DIRECTLY IN THIS LOOP?
        new = m.upper() + str(i)
        print(new)
        s = s.replace('{' + m + '}', new)    # BAD here because: 1) s.replace is not ok! bug if "m" is here mutliple times   
                                             #                   2) modifying s while looping on f(.., s) is probably not good
        a, b = do_something_else(a, b)
    return s

main('hell{o} this {is} a t{est}')    # hellO1 this IS2 a tEST3

下面的代码(with 一个替换函数)可以工作,但是全局变量的使用在这里是个大问题,因为实际上 do_something_else() 可能需要几毫秒,并且此过程可能与 main() 的另一个并发 运行 混合:

import re

def replace(m):
    global i, a, b
    a, b = do_something_else(a, b)
    i += 1
    return m.group(1).upper() + str(i)

def main(s):
    global i, a, b
    i = 0
    a, b = 0, 0
    return re.sub(r"{([^{}]+)}", replace, s)

main('hell{o} this {is} a t{est}')

使用finditer。示例:

import re
s = 'hell{o} this {is} a t{est}'
counter = 1
newstring = ''
start = 0
for m in re.finditer(r"{([^{}]+)}", s):
    end, newstart = m.span()
    newstring += s[start:end]
    rep = m.group(1).upper() + str(counter)
    newstring += rep
    start = newstart
    counter += 1
newstring += s[start:]
print(newstring)  # hellO1 this IS2 a tEST3