re.sub('a(b)','d','abc')
会产生dc
,而非adc
。那么为什么re.sub
不理解这里的捕获组呢?
答案 0 :(得分:9)
因为它应该替换整个模式:
返回通过替换repl替换字符串中最左边不重叠的模式而获得的字符串。
如果只替换某个子组,那么具有多个组的复杂正则表达式将不起作用。有几种可能的解决方案:
re.sub('ab', 'ad', 'abc')
- 我最喜欢的,因为它非常易读且清晰。re.sub('(a)b', r'\1d', 'abc')
repl
参数,并使其处理Match
对象并返回所需的结果。re.sub('(?<=a)b', r'd', 'abxb')
会产生adxb
。小组开头的?<=
说“这是一个先行”。答案 1 :(得分:0)
import re
pattern = re.compile(r"I am (\d{1,2}) .*", re.IGNORECASE)
text = "i am 32 years old"
if re.match(pattern, text):
print(
re.sub(pattern, r"Your are \1 years old.", text, count=1)
)
如上所述,首先我们使用不区分大小写的标志编译正则表达式模式。
然后我们检查文本是否与模式匹配,如果匹配,我们引用正则表达式(年龄)中唯一具有组号\ 1的组。
答案 2 :(得分:0)
因为这正是re.sub()
文档告诉您的事情:
'a(b)'
表示“匹配'a',带有可选的结尾'b'”。 (它可以单独匹配“ a”,但是不可能像您期望的那样单独匹配“ b”。如果您要这样做,请使用非贪婪的(a)??b
)。< / li>
如果要获得所需的输出,则需要在'(a)??'
上进行非贪心匹配:
>>> re.sub('(a)??b','d','abc')
'dc'
答案 3 :(得分:0)
我知道这不是严格回答 OP 问题,但是这个问题可能很难用 google 搜索(被 \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]:]
我知道这是想要的行为,但我仍然不明白为什么 re.sub 不能指定它应该替换的实际捕获组...