2013-01-08 260 views
6

能有人请解释.+.+?“。+”和“。+?”之间的区别

的区别我有字符串:"extend cup end table"

  1. 模式e.+d的发现:extend cup end
  2. 模式e.+?d的发现:extendend

我知道+是一个或多个,而?是一个或零。 但我无法理解它是如何工作的。

+0

如下所述,它是贪婪和惰性量词的区别。贪婪要尽可能多地消耗,尽可能少地懒惰。当量词懒惰时,引擎将按照字符从左到右“建立字符串”字符。贪婪会做相反的事情。如果需要,它将尽可能多地消耗,然后从右向左放下几个字符。查看以下示例:http://regex101.com/r/dG9zZ2和http://regex101.com/r/tP5xQ3 –

回答

16

两者都会匹配任何一个或多个字符的序列。不同之处在于:

  • .+贪婪和消耗尽可能多的字符就可以了。
  • .+?不情愿并消耗尽可能少的字符。

请参阅Java教程中的Differences Among Greedy, Reluctant, and Possessive Quantifiers

因此:

  • e.+d查找以e开头和结尾d(和包含在它们之间的至少一个字符)的最长子串。
  • e.+?d找到最短的这样的子字符串。在你的例子中,extendend是两个这样的非重叠匹配,所以它找到了两个。
+0

刚刚在rubular.com上测试了这些表达式,而且我实际上为什么要添加?使表达式忽略“杯”。虽然你的答案并没有详细解释。是否可以添加一行或两行? – Henrik

+0

@Henrik结果是这样的问题,原始问题中有奇怪的格式,我第一次尝试没有正确编辑 – Kapep

5

e.+?d匹配的'e',然后尝试尽可能少的字符匹配越好(ungreedy或不愿意)正则表达式,随后'd'。这就是为什么以下2子串匹配:

extend cup end table 
^^^^^^  ^^^ 
    1   2 

e.+d匹配的'e',然后尝试尽可能多的字符匹配越好(贪婪)正则表达式,随后'd'。什么情况是,第一'e'被发现,然后.+比赛一样,因为它可以(到行的末尾,或输入):

extend cup end table 
^^^^^^^^^^^^^^^^^^^^ 

正则表达式引擎涉及到行的末尾(或输入),并且不能匹配正则表达式模式中的'd'。所以它回溯到最后的'd'被看到。这就是为什么找到单个匹配:

extend cup end table 
^^^^^^^^^^^^^^<----- backtrack 
    1