Как l oop сверх совпадений регулярных выражений и выполнить замену, не используя отдельную функцию замены? - PullRequest
0 голосов
/ 13 апреля 2020

Мне нужно заменить каждый шаблон, например: {foo} на FOO + увеличивающееся число, а также do_something_else(...) для каждого матча. Пример:

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

Как это сделать без использования функции замены , но только с al oop над совпадениями ? Я ищу что-то вроде:

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}')

1 Ответ

1 голос
/ 13 апреля 2020

Используйте 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
print(newstring)  # hellO1 this IS2 a tEST3
...