我对以下三种模式感到困惑,有人能详细解释一下吗?在
## IPython with Python 2.7.3
In [62]: re.findall(r'[a-z]*',"f233op")
Out[62]: ['f', '', '', '', 'op', ''] ## why does the last '' come out?
In [63]: re.findall(r'([a-z])*',"f233op")
Out[63]: ['f', '', '', '', 'p', ''] ## why does the character 'o' get lost?
In [64]: re.findall(r'([a-z]*)',"f233op")
Out[64]: ['f', '', '', '', 'op', ''] ## what's the different than line 63 above?
例1
此模式匹配零个或多个小写字母字符实例。零或更多的部分在这里是关键的,因为从字符串中的每个索引位置开始的无任何匹配与}的匹配一样有效。返回的最后一个空字符串是从字符串结尾开始的匹配项(}(字符串结尾)之间的位置)。在
f
或{p
和{例2
^{pr2}$现在,您正在匹配字符组,由一个小写字母组成。不再返回}。同样,如果去掉字符串中的
o
,因为这是一个贪婪的搜索,并且将返回最后一个有效的匹配组。因此,如果您将字符串更改为f233op12fre
,则将返回最后的e
,但不会返回前面的f
或{p
,您仍然可以看到o
作为有效匹配返回。在相反,如果您试图通过添加
?
(例如([a-z])*?
)使此正则表达式非贪心的,则返回的匹配集将全部为空字符串,因为有效的nothing匹配的优先级高于某个内容的有效匹配。在例3
匹配的字符没有什么不同,但是现在返回的是字符组而不是原始匹配。此regex查询的输出将与第一个示例相同,但您会注意到,如果添加其他匹配组,您将突然看到将每个匹配尝试分组为元组的结果:
与相同的模式进行对比,去掉括号(组),你就会明白为什么它们很重要:
还有…
将这些regex模式插入到Regexplained等regex图生成器中,可以看到模式匹配逻辑是如何工作的。例如,为了解释regex为什么总是返回空字符串匹配,请看一下模式^{} 和{a3}之间的区别。在
如果遇到问题,不要忘了检查Python docs for the ^{} library ,它们实际上对标准regex语法给出了相当出色的解释。在
您的惊人结果与正则表达式量词
*
有关。在考虑:
Debuggex Demo
对比:
^{pr2}$Debuggex Demo
作为另一个例子,我认为它更能说明你所看到的:
字符串
123456789
中的集合[a-z]
中没有字符。然而,由于*
的意思是'零或更多',所有字符位置“匹配”的方式是不匹配该位置的任何字符。在例如,假设您只想测试字符串中是否有字母,并使用如下正则表达式:
现在考虑一下:
对比:
第一个模式是
[a-z]*
。部分[a-z]
是与集合a-z
中的一个单个字符匹配的字符类,除非修改;如果大于零,则添加*
量词将贪婪地匹配尽可能多的字符——因此匹配“abc”,但也允许零个字符匹配(或者字符集之外的字符匹配位置,因为0是匹配的)。在在
([a-z])*
中添加分组有效地将量化集中的匹配减少到单个字符,并返回集合中匹配的最后一个字符。在如果您想获得分组的效果(比如在更复杂的模式中),请使用非捕获组:
您得到了最后的
''
,因为[a-z]*
与末尾的空字符串匹配。缺少字符
'o'
,因为您已经告诉re.findall
匹配组,并且每个组都有一个字符。换句话说,你做的相当于它将返回
'p'
,因为这是parens(捕获组1)捕获的最后一个内容。同样,你是匹配组,但这次是多字符组。
相关问题 更多 >
编程相关推荐