我通过生成相对于整个字符串的所需捕获模式的“分组”版本来处理这个问题,然后直接将子表达式应用于该实例。
父函数是regex_n_sub
,并收集与re.sub()
方法相同的输入。
捕获模式通过将实例编号传递给get_nsubcatch_catch_pattern()
。在内部,列表推导式生成多个模式'.*?(匹配任何字符,0或多次重复,非贪婪)。此模式将用于表示捕获模式的前n个出现之间的空格。
接下来,输入的捕获模式被放置在每个“空格模式”的第n个位置,并用括号括起来形成第一组。
第二组只是用括号括起来的捕获模式-因此当两个组合并时,就会创建一个“所有文本直到第n次出现捕获模式”的模式。这个“new_catch_pattern”内置了两个组,因此可以替换包含第n次出现的捕获模式的第二个组。
替换模式被传递给get_nsubcatch_replace_pattern()
函数,并与前缀r'\g<1>'
组合形成模式\g<1> + replace_pattern
。该模式中的\g<1>
部分定位到捕获模式中的第1组,并用替换模式中的文本替换该组。
下面的代码仅为了更清晰地理解流程而冗长,可以根据需要进行简化。
--
以下示例应该可以独立运行,并将第4个"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
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()
函数调用。
如果实现失败,请告诉我!
谢谢!