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

问题描述

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

标签: pythonregexre

解决方案


使用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

推荐阅读