考虑:
text = "abcdef"
pattern = "(b|e)cd(b|e)"
repl = [r"\1bla\2", r"\1blabla\2"]
text = re.sub(pattern, lambda m: random.choice(repl), text)
Run Code Online (Sandbox Code Playgroud)
我想用列表的条目随机替换匹配项repl。但是,当使用lambda m: random.choice(repl)作为一个回调,它不会取代\1,\2其捕获更多的等等,返回"\1bla\2"为纯文本。
我试图查找re.py以了解他们如何在内部执行此操作,因此我可能能够调用相同的内部函数,但这似乎并不简单。
上面的示例返回a\1bla\2f或a\1blabla\2fwhileabblaef或abblablaef在我的情况下是有效的选项。
请注意,我使用的是一个函数,因为在有多个匹配项的情况下,例如text = "abcdef abcdef",它应该repl为每个匹配项随机选择一个替换项- 而不是对所有匹配项使用相同的替换项。
如果您传递一个函数,您将失去反向引用的自动转义。你只需要得到匹配对象就可以完成工作。所以你可以:
在正则表达式中选择一个字符串而不是传递一个函数:
text = "abcdef"
pattern = "(b|e)cd(b|e)"
repl = [r"\1bla\2", r"\1blabla\2"]
re.sub(pattern, random.choice(repl), text)
# 'abblaef' or 'abblablaef'
Run Code Online (Sandbox Code Playgroud)
或者编写一个函数来处理匹配对象并允许更复杂的处理。您可以利用expand使用反向引用:
text = "abcdef abcdef"
pattern = "(b|e)cd(b|e)"
def repl(m):
repl = [r"\1bla\2", r"\1blabla\2"]
return m.expand(random.choice(repl))
re.sub(pattern, repl, text)
# 'abblaef abblablaef' and variations
Run Code Online (Sandbox Code Playgroud)
当然,您可以将该函数放入 lambda 中:
repl = [r"\1bla\2", r"\1blabla\2"]
re.sub(pattern, lambda m: m.expand(random.choice(repl)), text)
Run Code Online (Sandbox Code Playgroud)