0

我需要替换每个模式,例如:{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

以下代码(带有替换函数)有效,但在这里使用全局变量是一个大问题,因为实际上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}')
4

1 回答 1

3

使用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
于 2020-04-13T14:42:10.983 回答