python re.sub 分组:\number 后的数字

294 投票
2 回答
142612 浏览
提问于 2025-04-16 17:32

我该怎么把 foobar 替换成 foo123bar 呢?

这个方法不行:

>>> re.sub(r'(foo)', r'\1123', 'foobar')
'J3bar'

这个方法可以:

>>> re.sub(r'(foo)', r'\1hi', 'foobar')
'foohibar'

2 个回答

1

对于这个问题,我更倾向于匹配但不捕获,使用以下方法。

re.sub(r'(?<=foo)', r'123', 'foobar')
  #=> 'foo123bar'

这个方法会把在 'foo' 之后(想象一下在 'foo''bar' 之间)的零宽字符串替换成 '123'(?<=foo) 是一个叫做 正向前瞻 的东西。

演示


当然,有些情况下需要用到捕获组,比如说

re.sub(r'(f\w*o)', r'\g<1>123', 'foobar')

这里

re.sub(r'(?<=f\w*o)', r'123', 'foobar')

就不行,因为Python默认的正则表达式引擎不支持可变长度的前瞻(不过可以使用另一个 PyPI正则模块 来实现)。

490

答案是:

re.sub(r'(foo)', r'\g<1>123', 'foobar')

以下是来自文档的相关摘录:

除了上面提到的字符转义和反向引用之外,\g<name>会使用由名为name的组匹配到的子字符串,这个组是通过(?P<name>...)这种语法定义的。\g<number>则使用对应的组编号;所以\g<2>\2是一样的,但在像\g<2>0这样的替换中不会产生歧义。\20会被理解为对组20的引用,而不是对组2的引用后面跟着一个字面字符'0'。反向引用\g<0>会替换为正则表达式匹配到的整个子字符串。

撰写回答