无法在 re.sub() repr 表达式的函数调用中使用“\1”反向引用捕获组

Pus*_*ush 2 python regex backreference substitution capture-group

我有一个字符串S = '02143'和一个列表A = ['a','b','c','d','e']。我想将 'S' 中的所有数字替换为 list 中相应的元素A。

例如,替换0为A[0]、2withA[2]等。最终输出应该是S = 'acbed'.

我试过:

S = re.sub(r'([0-9])', A[int(r'\g<1>')], S)
Run Code Online (Sandbox Code Playgroud)

然而这会产生错误ValueError: invalid literal for int() with base 10: '\\g<1>'。我猜它正在将反向引用'\g<1>'视为字符串。我该如何解决这个问题,特别是使用re.sub和捕获组,否则呢?

Wik*_*żew 5

re.sub(r'([0-9])',A[int(r'\g<1>')],S)不起作用的原因是\g<1>(这是第一个反向引用的明确表示,否则写为\1)反向引用仅在字符串替换模式中使用时才有效。如果将它传递给另一个方法,它只会“看到”\g<1>文字字符串,因为re模块当时没有任何机会对其进行评估。re引擎仅在匹配期间评估它,但在引擎尝试查找匹配A[int(r'\g<1>')]之前评估该部分。re

这就是为什么可以使用内部回调方法re.sub作为替换参数:您可以将匹配的组值传递给任何外部方法以进行高级操作。

请参阅re文档:

re.sub(pattern, repl, string, count=0, flags=0)

如果repl是一个函数,则每次不重叠出现 时都会调用它pattern。该函数采用单个匹配对象参数,并返回替换字符串。

使用

import re
S = '02143' 
A = ['a','b','c','d','e']
print(re.sub(r'[0-9]',lambda x: A[int(x.group())],S))
Run Code Online (Sandbox Code Playgroud)

查看Python 演示

请注意,您不需要使用括号捕获整个模式,您可以使用 访问整个匹配x.group()。