为啥 re.sub() 在 Python 中默认添加不匹配的字符串?

Posted

技术标签:

【中文标题】为啥 re.sub() 在 Python 中默认添加不匹配的字符串?【英文标题】:Why re.sub() adds not matched string by default in Python?为什么 re.sub() 在 Python 中默认添加不匹配的字符串? 【发布时间】:2021-12-20 09:25:30 【问题描述】:
import re

print(re.sub(
    r'(size:)\D+(\d+)\D+(\d+)\D+(\d+)',
    r'\2x\3x\4',
    'START, size: 100Х200 x 50, END'
))

输出:

'START, 100x200x50, END'

我不希望正则表达式中未提及的字符串部分。外面的一切——必须省略。

是的,如果我们通过在末尾和开头添加.* 来提及整个内容,它将按预期工作:

r'.*(size:)\D+(\d+)\D+(\d+)\D+(\d+).*'

输出将是:

'100x200x50'

...默认情况下(对我而言)应该是这样的。

为什么? =)

更新

是的,很明显,它正在寻找一个匹配来替换它。 (半夜加班不会太明显=D)

但最好有解决方案来避免匹配整个字符串。

【问题讨论】:

【参考方案1】:

re.sub替换匹配的部分,不匹配的部分保持不变是正常的。

您应该尝试匹配所有内容:

import re
print(re.sub(
    r'.*(size:)\D+(\d+)\D+(\d+)\D+(\d+).*',
    r'\2x\3x\4',
    'START, size: 100Х200 x 50, END'
))

输出:100x200x50

替代方案:re.search
import re
m = re.search(
    r'size:\D+(\d+)\D+(\d+)\D+(\d+)',
    'START, size: 100Х200 x 50, END'
)
print('x'.join(m.groups()) if m else 'no match')

【讨论】:

【参考方案2】:

您似乎对 sub 的功能有误解。它替换了匹配的正则表达式。此正则表达式 r'(size:)\D+(\d+)\D+(\d+)\D+(\d+)' 匹配您的字符串的一部分,因此只有匹配部分将被替换,捕获组不会影响这一点。 你可以做什么(如果你不想在开头和结尾添加.*,就像这样使用re.findall

re.findall(
    r'(size:)\D+(\d+)\D+(\d+)\D+(\d+)',
    'START, size: 100Х200 x 50, END'
    )

这将返回[('size:', '100', '200', '50')],然后您可以根据需要对其进行格式化。 一种方法是作为一个没有错误处理的班轮是这样的:

'1x2x3'.format(
    *re.findall(
        r'(size:)\D+(\d+)\D+(\d+)\D+(\d+)',
        'START, size: 100Х200 x 50, END')[0]
    )

【讨论】:

是的,答案可能是因为它正在寻找要替换的字符串。感谢您的回答! =) 我认为,'1x2x3'.format() 是我所需要的。谢谢!

以上是关于为啥 re.sub() 在 Python 中默认添加不匹配的字符串?的主要内容,如果未能解决你的问题,请参考以下文章

带有标志的 Python re.sub 不会替换所有出现

当我尝试在我的代码中使用 re.sub 表达式时,为啥会收到一个名为“预期字符串或类似对象的字节”的错误 [重复]

在Python中for循环和re.sub怎么一起用

详解Python中re.sub--转载

Python

如何在 Python 3.9 中从 re.sub 中删除反斜杠