Python 正则表达式:为什么 re.sub('a*', '-', 'abxd',count=1) = '-bxd'?不应该是“-abxd”吗?

Python regex: Why re.sub('a*', '-', 'abxd',count=1) = '-bxd' ? Shouldn't it be '-abxd'?

阅读 python 的 re 包的文档后。我认为结果应该是 re.sub('a*', '-', 'abxd',count=1) -> '-abxd' 。但是,我得到以下结果:

re.sub('a*', '-', 'abxd',count=1) -> '-bxd'

我真的很困惑,因为第一个匹配应该是 'abxd''a' 前面的空匹配。

特别是,我尝试了其他三个示例,得到了如下预期结果:

re.sub('a*', '-', '  abxd',count=1) -> '-  abxd'

re.sub('a*', '-', ' abxd',count=1) -> '- abxd'

re.sub('x*', '-', ' abxd',count=1) -> '-abxd'

非常感谢您的帮助。

a* 在当前位置匹配 尽可能多的 a 副本。它可以匹配零(不像a+),但如果有的话,它会匹配所有。

考虑一下 findall 对您的示例做了什么:

>>> re.findall(r'(a*)', 'abcd')
['a', '', '', '', '']

五个匹配项,第一个是最简单和最明显的:匹配 a。下一个是 0 or more 匹配每个字符边界:

for i in range(len(re.findall(r'a*', 'abcd'))):
    s_sub=re.sub(r'a*', '-', 'abcd', count=i+1)
    print(f' sub {i+1}: {s_sub}')

打印:

sub 1: -bcd
sub 2: --bcd
sub 3: --b-cd
sub 4: --b-c-d
sub 5: --b-c-d-

如果你仔细想想,这才是正确的做法。

如果你有re.sub('a*', '-', 'aaaabxd',count=1),你会期望:

  1. 第一个匹配是在字符串开头的字符边界插入-得到'-aaabxd'
  2. a 之后得到 'aaa-bxd'
  3. 您是否认为 a* 意味着尽可能多的 a 导致 '-bxd'

第三个选项是 a*:

>>> re.sub('a*', '-', 'aaaabxd',count=1)
'-bxd'

此行为是 quantifier * 贪婪的结果。 正则表达式语言中有一个元字符表示 不要贪婪,当与 +* 量词组合时 是 LAZY[=30] =].如果您使用它,它会导致您期望的行为,因为匹配所有 a 的第一个明显匹配被跳过:

>>> re.sub('a*?', '-', 'aaaabxd',count=1)
'-aaaabxd' 

并且:

s='aabcd'
for i in range(len(re.findall(r'a*?', s))):
    s_sub=re.sub(r'a*?', '-', s, count=i+1)
    print(f'sub {i+1}: {s_sub}')

打印:

sub 1: -aabcd
sub 2: --abcd
sub 3: ---abcd
sub 4: ----bcd
sub 5: -----bcd
sub 6: -----b-cd
sub 7: -----b-c-d
sub 8: -----b-c-d-