Python re.sub组:\数字后面的数字

289

我该如何将foobar替换为foo123bar

以下方法无法实现:

>>> re.sub(r'(foo)', r'\1123', 'foobar')
'J3bar'
这是可行的:
>>> re.sub(r'(foo)', r'\1hi', 'foobar')
'foohibar'

我认为当使用像\number这样的东西时,这是一个常见的问题。有人能给我提示如何处理吗?


2
此问题已添加到Stack Overflow正则表达式FAQ,位于“分组”下。 - aliteralmind
2
这个问题让我花了很长时间才找到,因为它并没有涉及到“捕获组”或“编号组引用”这些术语,但最终我找到了并且很高兴你提出了这个问题。 - Mark Ch
1
你的问题是r'\112'被解释为八进制字面量0112,ASCII码为'J'或十进制数74。看不到如何在字符串连接或'' .join()之前强制执行反向引用'\1'的求值。 - smci
有一个与问题略微偏离的小问题,是否有办法引用所有组匹配,即r'<for all matches>hi'? - user11370656
1个回答

482

答案是:

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

来自文档的相关摘录:

除了上面描述的字符转义和反向引用之外, \g 还将使用按 (?P...) 语法定义的名为 name 的组匹配的子字符串。 \g 使用相应的组号; 因此,\g<2> 等同于 \2,但在 \g<2>0 等替换中不会产生歧义。 \20 将被解释为对第 20 组的引用,而不是对第 2 组后跟文字 '0' 的引用。 反向引用 \g<0> 替换整个由 RE 匹配的子字符串。


80
别太苛求自己了。这个答案已经 深深地埋藏在文档 里面,读文档的时间比谷歌搜索问题并在 Stack Overflow 找到这个答案的时间还要长得多。请注意不要修改原意,让翻译更通俗易懂。 - speedplane
1
如果您需要上下文,可以在此处找到提供的确切引用。 - patrick
我可以取出这个组并修改它吗?\g<1> ... 例如,在这种情况下,g<1>是foo,但我想把o改成u,就像这样“fuu”。 - Eric Bellet
1
@EricBellet 你很可能需要用几行代码来实现。即使可以在一行中实现,也不容易维护,不值得冒这个风险。如果你正在进行代码高尔夫比赛,那么有一种条件匹配和使用命名组引用匹配字符的方法。例如,在Python中查找单引号或双引号文本,可以使用(?P<q>['"])(.*)(?P=q),其中(?P=q)引用了命名组(?P<q>['"])。例如,如果第一个字符是单引号,则最后一个组只会匹配单引号。 - Fred Dufresne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接