【问题标题】: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)

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

【问题讨论】:

    标签: python regexp-replace


    【解决方案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')],然后您可以根据需要对其进行格式化。 一种方法是作为一个没有错误处理的班轮是这样的:

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

      【讨论】:

      • 是的,答案可能是因为它正在寻找要替换的字符串。感谢您的回答! =)
      • 我认为,'{1}x{2}x{3}'.format() 是我所需要的。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 2011-09-17
      • 2020-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多