>>> re.findall(r"(?:do|re|mi)+", "mimi")
['mimi']
>>> re.findall(r"(do|re|mi)+", "mimi")
['mi']
根据我对the definitions的理解,它应该产生相同的答案。 (...)
和(?:...)
之间的唯一区别应该是我们是否可以在以后使用反向引用。我错过了什么吗?
(...)
匹配括号内的正则表达式,并指示组的开始和结束;在执行匹配后,可以检索组的内容,并且可以在字符串中稍后使用\ number特殊序列进行匹配,如下所述。要匹配文字'('或')',请使用(或)或将它们包含在字符类中:[(] [)]。
(?:...)
常规括号的非捕获版本。匹配括号内的正则表达式,但在执行匹配后或在模式中稍后引用时,无法检索组匹配的子字符串。
答案 0 :(得分:4)
(?:...)
没有分组。所以,在
re.findall(r"(?:do|re|mi)+", "mimi")
它为整个正则表达式的每个匹配返回一个值,在这种情况下是mi
字符串的两倍,因此列表中包含一个元素mimi
。
(...)
进行分组,findall()
将为匹配的每个带括号的字符串返回一个值。在
re.findall(r"(do|re|mi)+", "mimi")
匹配mi
并将其保存为组1,然后继续并再次匹配mi
,但在同一个带括号的字符串中,因此覆盖组1,最后它返回组中的值1,它只是第二mi
。
答案 1 :(得分:1)
不,你没有遗漏任何东西。使用(?:...)
是为了能够对事物进行分组,而不会在反向引用/匹配的子字符串中放入不需要的项。
答案 2 :(得分:1)
虽然匹配相同,但非分组版本(?...)
: