在以下示例中,我正在尝试创建一个正则表达式来查找一行中一个或多个连续数字的最后一组。
据我所知,在python3中,re.search()遍历搜索字符串,试图从左到右匹配。
这可以解释下面例子中的行为吗?具体来说,是'。*?'的原因在捕获块之前需要(当锚定到前面时,如前两个示例中所示),以便捕获块捕获两个数字,而'?'当正则表达式锚定到行的末尾时是可选的(如前两个示例中所示?)
Python 3.1.2 (release31-maint, Sep 17 2010, 20:27:33)
>>> import re
>>> a = "hi there in the morning {23)"
>>> R = re.compile('^.*(\d+)', re.IGNORECASE); print(R.search(a).group(1))
3
>>> R = re.compile('^.*?(\d+)', re.IGNORECASE); print(R.search(a).group(1))
23
>>> R = re.compile('(\d+).*$', re.IGNORECASE); print(R.search(a).group(1))
23
>>> R = re.compile('(\d+).*?$', re.IGNORECASE); print(R.search(a).group(1))
23
答案 0 :(得分:4)
^.*(\d+)
- 从头开始比赛。 .*
将一直匹配到该行的结尾,然后\d+
将.*
回溯(取消之前的匹配),尽可能少,因此\d+
只会匹配最后一位。^.*?(\d+)
- 从头开始比赛。 .*?
一开始就没有匹配。 \d+
稍后会失败(如果第一个字符不是数字),请.*?
回溯,并匹配额外字符,直到找到第一个数字,然后{{ 1}}将匹配其后的所有数字。对于+
,模式将匹配abc123edf567
,第一组数字。123
- (\d+).*$
将匹配第一组数字。 \d+
将始终成功并一直匹配到最后。.*$
- 这个实际上是相同的(尽管可能略微慢一点)。 (\d+).*?$
将匹配第一组数字。 \d+
一开始不会匹配任何内容,但会匹配越来越多的字符,直到达到.*?$
。请注意,$
在左侧是懒惰的,但并不意味着引擎将从右侧获取所需的字符。您可能正在寻找的是*?
- 匹配一组字符,后跟非字符和行尾。这将返回最后一组数字。
另请参阅:regular-expressions.info - Laziness Instead of Greediness
答案 1 :(得分:3)
单凭*
贪婪;它会尽可能地匹配,同时允许正则表达式作为一个整体匹配,因此.*
会吞噬除匹配\d+
所需的单个数字之外的所有内容。
*?
使用非贪婪匹配,因此只有非数字匹配。
答案 2 :(得分:0)
正如Wooble所说,。*是贪婪的,所以在第一个例子的字符串中,。*?
的最贪婪匹配将是hi there in the morning {2
,因为\d+
只适用于一个值,3
。