我无法理解以下输出:
import re
re.sub(r'(?:\s)ff','fast-forward',' ff')
'fast-forward'
根据文件:
返回通过替换repl替换字符串中最左边不重叠的模式而获得的字符串。
那么为什么包含在捕获的出现中的空白,然后被替换,因为我之前添加了一个非捕获标记?
我想得到以下输出:
' fast-forward'
答案 0 :(得分:2)
non-capturing group仍匹配,消费匹配的文字。请注意,消费意味着将匹配的文本添加到匹配值(为整个匹配的子字符串分配的内存缓冲区)和相应的正则表达式索引的推进。因此,(?:\s)
会将空白放入匹配值中,并将其替换为ff
。
您希望使用look-behind检查模式而不使用它:
re.sub(r'(?<=\s)ff','fast-forward',' ff')
请参阅regex demo。
这种方法的另一种方法是在需要保留的模式部分周围使用捕获组,并在替换模式中使用替换反向引用:
re.sub(r'(\s)ff',r'\1fast-forward',' ff')
^ ^ ^^
这里,(\s)
将空白保存在组1内存缓冲区中,替换中的\1
检索它并添加到替换字符串结果中。
请参阅Python demo:
import re
print('"{}"'.format(re.sub(r'(?<=\s)ff','fast-forward',' ff')))
# => " fast-forward"
答案 1 :(得分:0)
非捕获组仍然匹配其包含的模式。你想要表达的是一个后视,它与它的模式不匹配,但只是声称它在你的比赛之前存在。
虽然,如果您要使用后视空格,您可能需要考虑使用单词边界元字符\b
。它匹配\w
和\W
字符之间的空字符串,断言您的模式位于单词的开头。
import re
re.sub(r'\bff\b', 'fast-forward', ' ff') # ' fast-forward'
添加尾随\b
还可确保只有'ff'
匹配'ffoo'
,如果它被空格包围,而不是ngIf
中的单词的开头。
请参阅demo。