重新上传捕获组

Nic*_*ick 8 python regex replace capturing-group python-3.x

re.sub('a(b)','d','abc')收益率dc,而不是adc.那么为什么不re.sub理解这里的捕获组呢?

yep*_*ons 14

因为它应该替换模式的整个出现:

返回通过替换repl替换字符串中最左边不重叠的模式而获得的字符串.

如果它只替换一些子组,那么具有多个组的复杂正则表达式将不起作用.有几种可能的解决方案:

  1. 完整指定模式:re.sub('ab', 'ad', 'abc')- 我最喜欢的,因为它非常易读和明确.
  2. 捕获保留的组,然后在模式中引用它们(请注意它应该是原始字符串以避免转义):re.sub('(a)b', r'\1d', 'abc')
  3. 与前一个选项类似:提供一个回调函数作为repl参数,并使其处理Match对象并返回所需的结果.
  4. 使用lookbehinds/lookaheds,它们不包含在匹配中,但会影响匹配:re.sub('(?<=a)b', r'd', 'abxb')yield adxb.将?<=在该组的开头说:"这是一个超前".

  • 只是一个快速提示:您可以在正则表达式中使用 `\1` **:`re.match(r'([la]{2})-\1', 'la-la')`。它将匹配引用的内容(在这种情况下为`1`)**匹配**(不是模式),因此这个正则表达式不会匹配`la-al`。 (2认同)

Mr *_*son 5

我知道这并不是严格回答OP问题,但是这个问题很难用谷歌搜索(被 \1 解释淹没......)

对于那些像我一样来到这里的人,因为他们想实际用字符串替换不是第一个的捕获组,而不需要对字符串或正则表达式有特殊的了解:

#find offset [start, end] of a captured group within string
r = regex.search(oldText).span(groupNb)
#slice the old string and insert replacementText in the middle 
newText = oldText[:r[0]] + replacementText + oldText[r[1]:]
Run Code Online (Sandbox Code Playgroud)

我知道这是想要的行为,但我仍然不明白为什么 re.sub 无法指定它应该替换的实际捕获组...