具有非捕获字符的 python re.sub() 的意外结果

pla*_*nne 4 python regex

我无法理解以下输出:

import re 

re.sub(r'(?:\s)ff','fast-forward',' ff')
'fast-forward'
Run Code Online (Sandbox Code Playgroud)

根据文档:

返回通过替换 repl 替换 string 中模式的最左侧非重叠出现而获得的字符串。

那么为什么空格包含在捕获的出现中,然后被替换,因为我在它之前添加了一个非捕获标签?

我想要以下输出:

' fast-forward'
Run Code Online (Sandbox Code Playgroud)

Wik*_*żew 6

非捕获组仍然匹配消耗匹配的文本。请注意,消耗意味着将匹配的文本添加到匹配值(为整个匹配的子字符串分配内存缓冲区)以及相应的正则表达式索引的推进。因此,(?:\s)将空格放入匹配值中,并将其替换为ff.

您想使用后检查模式而不消耗它:

re.sub(r'(?<=\s)ff','fast-forward',' ff')
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示

这种方法的另一种方法是在需要保留的模式部分周围使用捕获组,并在替换模式中使用替换反向引用:

re.sub(r'(\s)ff',r'\1fast-forward',' ff')
         ^  ^      ^^ 
Run Code Online (Sandbox Code Playgroud)

在这里,(\s)将空白保存在第 1 组内存缓冲区中,并\1在替换中检索它并将其添加到替换字符串结果中。

请参阅Python 演示

import re 
print('"{}"'.format(re.sub(r'(?<=\s)ff','fast-forward',' ff')))
# => " fast-forward"
Run Code Online (Sandbox Code Playgroud)