具有非捕获字符

时间:2018-06-14 12:30:09

标签: python regex

我无法理解以下输出:

import re 

re.sub(r'(?:\s)ff','fast-forward',' ff')
'fast-forward'

根据文件:

  

返回通过替换repl替换字符串中最左边不重叠的模式而获得的字符串。

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

我想得到以下输出:

' fast-forward'

2 个答案:

答案 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