python re.sub 分组:\number 后的数字
我该怎么把 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>
会替换为正则表达式匹配到的整个子字符串。