在 re.sub 中传递函数时获取匹配号

Getting the match number when passing a function in re.sub

使用 re.sub 中的函数时:

import re
def custom_replace(match):
    # how to get the match number here? i.e. 0, 1, 2
    return 'a'
print(re.sub(r'o', custom_replace, "oh hello wow"))

如何获取custom_replace里面的匹配号?

即0、1、2为三个"o"的示例输入字符串。

注意:我不想为此使用全局变量,因为多个这样的操作可能发生在不同的线程等中。

似乎没有内置的方法。您可以使用全局变量作为计数器。

def custom_replace(match):
    global match_num
    result = 'a' + str(match_num)
    match_num += 1
    return result

match_num = 0
print(re.sub(r'o', custom_replace, "oh hello wow"))

输出为

a0h hella1 wa2w

不要忘记在每次使用此函数调用 re.sub() 之前将 match_num 重置为 0

根据@Barmar 的回答,我尝试了这个:

import re

def custom_replace(match, matchcount):
    result = 'a' + str(matchcount.i)
    matchcount.i += 1
    return result

def any_request():
    matchcount = lambda: None  # an empty "object", see 
    matchcount.i = 0           # benefit : it's a local variable that we pass to custom_replace "as reference
    print(re.sub(r'o', lambda match: custom_replace(match, matchcount), "oh hello wow"))
    # a0h hella1 wa2w

any_request()

它似乎有效。

原因:我有点不愿意为此使用全局变量,因为我在 Web 框架中的路由函数(此处称为 any_request())中使用它。
假设有许多并行请求(在线程中),我不希望全局变量在不同调用之间为 "mixed"(因为操作可能不是原子的?)

您可以将 re.searchre.sub 一起使用。

def count_sub(pattern,text,repl=''):
    count=1
    while re.search(pattern,text):
        text=re.sub(pattern,repl+str(count),text,count=1)
        count+=1
    return text

输出:

count_sub(r'o', 'oh hello world')
# '1h hell2 w3rld'

count_sub(r'o', 'oh hello world','a')
# 'a1h hella2 wa3rld'

选择:

def count_sub1(pattern,text,repl=''):
    it=enumerate(re.finditer(pattern,text),1)
    count=1
    while count:
        count,_=next(it,(0,0))
        text=re.sub(pattern,repl+str(count),text,count=1)
    return text

输出:

count_sub1(r'o','oh hello world')
# '1h hell2 w3rld'

count_sub1(r'o','oh hello world','a')
# 'a1h hella2 wa3rld'