re.sub没有像我预期的那样行事,请解释一下这里发生了什么



为了简化,假设我有以下代码:

import re
line = '(5) 3:16 The footnote explaination for footnote number one here.'
# trying to match a literal open parenthesis, followed by a number,
# followed by closing parenthesis - with match.group(1) being the number.
match = re.match(r'((d+))', line)

reordered_num = 1
renumbered_line_1 = re.sub(match.group(0), '{}'.format(reordered_num), line )
renumbered_line_2 = re.sub(match.group(1), '{}'.format(reordered_num), line )

我预计CCD_ 1已经取代了";1〃;代替";(5( ";在文本中。

我预计CCD_ 2已经取代了";1〃;代替";5〃;在文本中。

问题:为什么renumbered_line_1renumbered_line_2都有完全相同的内容是:

(1) 3:16 The footnote explaination for footnote number one here

这是Mac上运行的Python 3.9.7的错误吗。。。还是有什么我不理解的地方?

Python 3.9.7 (default, Sep  3 2021, 12:45:31)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>>
>>> line = '(5) 3:16 The footnote explaination for footnote number one here.'
>>>
>>> # trying to match a literal open parenthesis, followed by a number,
>>> # followed by closing parenthesis - with match.group(1) being the number.
>>> match = re.match(r'((d+))', line)
>>>
>>>
>>> reordered_num = 1
>>>
>>> renumbered_line_1 = re.sub(match.group(0), '{}'.format(reordered_num), line )
>>> renumbered_line_2 = re.sub(match.group(1), '{}'.format(reordered_num), line )
>>>
>>> renumbered_line_1
'(1) 3:16 The footnote explaination for footnote number one here.'
>>> renumbered_line_2
'(1) 3:16 The footnote explaination for footnote number one here.'
>>>

代码中match.group(0)match.group(1)的结果分别为(5)5。这就是你正在做的:

>>> re.sub('(5)', '1', '(5) 3:16 the footnote')
'(1) 3:16 the footnote'
>>> re.sub('5', '1', '(5) 3:16 the footnote')
'(1) 3:16 the footnote'

在这两种情况下仅替换renumbered_line_10的原因是图案(5)是组内的单个字符5。它匹配(并捕获(字符串中的单个字符5,因此这就是您要替换的内容。

如果要替换包含括号的字符串(5),可以执行以下操作之一:

  • 手动转义括号:
    re.sub(r'(5)', '1', '(5) 3:16 the footnote')
    
  • 使用re.escape转义括号:
    re.sub(re.escape('(5)'), '1', '(5) 3:16 the footnote')
    
  • 使用非正则表达式替换:
    '(5) 3:16 the footnote'.replace('(5)', '1')
    

我建议使用第三个选项,因为在代码的这一点上,您似乎没有尝试使用regex功能。

所以它在你的代码中看起来是这样的:

renumbered_line_1 = line.replace(match.group(0), str(reordered_num))

相关内容

最新更新