我通过相对于整个字符串生成所需捕获模式的“分组”版本来解决此问题,然后将子直接应用于该实例。
父函数是regex_n_sub,它收集与re.sub() 方法相同的输入。
catch 模式 与实例编号一起传递给get_nsubcatch_catch_pattern()。在内部,列表推导式生成模式 '.*? 的倍数(匹配任何字符,0 次或多次重复,非贪婪)。此模式将用于表示第 n 次出现 catch_pattern 之间的空间。
接下来,输入 catch_pattern 被放置在每个“空间模式”的第 n 个之间,并用括号括起来以形成 第一组。
第二组只是括在括号中的 catch_pattern - 所以当两个组组合在一起时,'直到第 n 次出现 catch 模式的所有文本的模式 被创建。这个“new_catch_pattern”内置了两个组,因此可以替换包含第 n 次出现的 catch_pattern 的第二组。
替换模式 被传递给get_nsubcatch_replace_pattern() 并与前缀r'\g<1>' 组合形成模式\g<1> + replace_pattern。此模式的 \g<1> 部分从 catch 模式中定位第 1 组,并用替换模式中的文本替换该组。
下面的代码是冗长的,只是为了更清楚地理解流程;可以根据需要减少。
--
下面的示例应该独立运行,并将“I”的第四个实例更正为“me”:
“当我一个人去公园时,我想鸭子会嘲笑我,但我不确定。”
与
“当我一个人去公园时,我觉得鸭子会笑话我,但我不确定。”
import regex as re
def regex_n_sub(catch_pattern, replace_pattern, input_string, n, flags=0):
new_catch_pattern, new_replace_pattern = generate_n_sub_patterns(catch_pattern, replace_pattern, n)
return_string = re.sub(new_catch_pattern, new_replace_pattern, input_string, 1, flags)
return return_string
def generate_n_sub_patterns(catch_pattern, replace_pattern, n):
new_catch_pattern = get_nsubcatch_catch_pattern(catch_pattern, n)
new_replace_pattern = get_nsubcatch_replace_pattern(replace_pattern, n)
return new_catch_pattern, new_replace_pattern
def get_nsubcatch_catch_pattern(catch_pattern, n):
space_string = '.*?'
space_list = [space_string for i in range(n)]
first_group = catch_pattern.join(space_list)
first_group = first_group.join('()')
second_group = catch_pattern.join('()')
new_catch_pattern = first_group + second_group
return new_catch_pattern
def get_nsubcatch_replace_pattern(replace_pattern, n):
new_replace_pattern = r'\g<1>' + replace_pattern
return new_replace_pattern
### use test ###
catch_pattern = 'I'
replace_pattern = 'me'
test_string = "When I go to the park and I am alone I think the ducks laugh at I but I'm not sure."
regex_n_sub(catch_pattern, replace_pattern, test_string, 4)
此代码可以直接复制到工作流中,并将替换的对象返回给regex_n_sub() 函数调用。
如果实施失败请告诉我!
谢谢!