在正则表达式的上下文中,"懒惰"和"贪婪"是什么意思?

ajs*_*sie 474 regex non-greedy regex-greedy

有人能以一种可以理解的方式解释这两个术语吗?

Sam*_*son 592

贪婪会尽可能多地消耗掉.从http://www.regular-expressions.info/repeat.html我们看到尝试匹配HTML标签的示例<.+>.假设您有以下内容:

<em>Hello World</em>
Run Code Online (Sandbox Code Playgroud)

您可能认为<.+>(.意味着任何非换行符并且+意味着一个或多个)只会匹配<em></em>,而实际上它将非常贪婪,并从第一个<到最后一个>.这意味着它将匹配<em>Hello World</em>而不是您想要的.

使它懒惰(<.+?>)将防止这种情况.通过添加?之后+,我们告诉它重复尽可能少的次数,所以>它遇到的第一个,就是我们想要停止匹配的地方.

我鼓励你下载RegExr,这是一个很棒的工具,可以帮助你探索正则表达式 - 我一直都在使用它.

  • 它只匹配一次,从第一个**<**开始到最后一个**>**结束. (9认同)
  • 只是补充说,还有一种贪婪的方式:`<[^>] +>`https://regex101.com/r/lW0cY6/1 (8认同)
  • 作为记录,关于在 HTML 中使用正则表达式 /sf/ask/121264391/ except-xhtml-self-contained-tags (4认同)
  • 但是让它变得懒惰会匹配两次,给我们打开和关闭标签,忽略它们之间的文本(因为它不适合表达式). (3认同)
  • 所以如果你使用贪婪,你会有3个(1个元素+ 2个标签)匹配还是只有1个匹配(1个元素)? (2认同)

sle*_*man 280

'贪婪'意味着匹配最长的字符串.

'懒惰'意味着匹配最短的字符串.

例如,贪婪的h.+l比赛'hell''hello',但懒惰的h.+?l比赛'hel'.

  • 辉煌,懒惰会在条件l满足后立即停止,但贪婪意味着只有在条件l不再满足后它才会停止? (84认同)
  • 对于阅读帖子的所有人来说:贪婪或懒惰的量词本身与最长/最短的子串不匹配.您必须使用[**贪婪的贪婪令牌**](http://www.rexegg.com/regex-quantifiers.html#tempered_greed),或使用非正则表达式方法. (3认同)
  • @AndrewS不要被示例中的双ll混淆.它相当懒惰将匹配最短的子串,而贪婪将匹配最长的子串.贪婪的'h.+ l`匹配''helolo'中的`'helol'`,但懒惰的`h.+?l`匹配''hel'. (3认同)
  • @FloatingRock:不.`x?`表示`x`是可选的,但`+?`是不同的语法.这意味着停止寻找匹配的东西 - 懒惰匹配. (3认同)
  • @FloatingRock:至于如何区分不同的语法,很简单:“?”表示可选,“+?”表示惰性。因此“\+?”意味着“+”是可选的。 (2认同)

Pre*_*raj 101

+-------------------+-----------------+------------------------------+
| Greedy quantifier | Lazy quantifier |        Description           |
+-------------------+-----------------+------------------------------+
| *                 | *?              | Star Quantifier: 0 or more   |
| +                 | +?              | Plus Quantifier: 1 or more   |
| ?                 | ??              | Optional Quantifier: 0 or 1  |
| {n}               | {n}?            | Quantifier: exactly n        |
| {n,}              | {n,}?           | Quantifier: n or more        |
| {n,m}             | {n,m}?          | Quantifier: between n and m  |
+-------------------+-----------------+------------------------------+
Run Code Online (Sandbox Code Playgroud)

加一个?一个量词使它不合适,即懒惰.

实施例:
测试字符串:计算器
贪婪reg表达式:s.*o输出:stackoverflo瓦特
懒惰reg表达式:s.*?o输出:stacko verflow

  • @BreakingBenjamin:不?不等于?,当它可以选择返回0或1时,它将选择0(懒惰)替代.要查看差异,请比较`re.match('(f)?(.*)','food').groups()`到`re.match('(f)??(.*)','食品").组()`.在后者中,`(f)??`与前导'f'不匹配,即使它可以.因此'f'将被第二个'.*'捕获组匹配.我确定你可以用'{n}构建一个例子吗?太.不可否认,这两个很少使用. (4认同)
  • 不是 ??相当于 ?.同样,不是{n}?等于{n} (2认同)
  • @Number945 是的,“{n}?”相当于“{n}”。请参阅/sf/ask/1260426541/ (2认同)

Car*_*rum 54

贪婪意味着你的表达式将尽可能地匹配一个组,懒惰意味着它将匹配可能的最小组.对于这个字符串:

abcdefghijklmc
Run Code Online (Sandbox Code Playgroud)

这个表达式:

a.*c
Run Code Online (Sandbox Code Playgroud)

贪婪的匹配将匹配整个字符串,而惰性匹配将匹配第一个abc.

  • 对于其他想知道的人来说,上面提到的表达式“a.*c”是贪婪的,而“a.*?c”则是惰性的对应表达式。 (3认同)

Eug*_*ene 14

据我所知,大多数正则表达式引擎默认是贪心的.在量词的末尾添加问号将启用延迟匹配.

正如@Andre S在评论中提到的那样.

  • 贪心:继续搜索,直到条件不满意为止.
  • 懒惰:一旦条件满足就停止搜索.

请参阅下面的示例,了解贪婪和懒惰的内容.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String args[]){
        String money = "100000000999";
        String greedyRegex = "100(0*)";
        Pattern pattern = Pattern.compile(greedyRegex);
        Matcher matcher = pattern.matcher(money);
        while(matcher.find()){
            System.out.println("I'm greeedy and I want " + matcher.group() + " dollars. This is the most I can get.");
        }

        String lazyRegex = "100(0*?)";
        pattern = Pattern.compile(lazyRegex);
        matcher = pattern.matcher(money);
        while(matcher.find()){
            System.out.println("I'm too lazy to get so much money, only " + matcher.group() + " dollars is enough for me");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


结果是:

我很开心,我想要1亿美元.这是我能得到的最多.

我懒得拿那么多钱,只有100美元对我来说已经足够了

  • 我非常喜欢你的榜样. (4认同)

Sel*_*lva 10

贪心匹配。正则表达式的默认行为是贪婪的。这意味着它会尝试尽可能多地提取,直到它符合模式,即使较小的部分在语法上就足够了。

\n\n

例子:

\n\n
import re\ntext = "<body>Regex Greedy Matching Example </body>"\nre.findall(\'<.*>\', text)\n#> [\'<body>Regex Greedy Matching Example </body>\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

它不是匹配到第一次出现 \xe2\x80\x98>\xe2\x80\x99,而是提取整个字符串。这是正则表达式的默认贪婪或 \xe2\x80\x98take it all\xe2\x80\x99 行为。

\n\n

另一方面,惰性匹配\xe2\x80\x98 需要尽可能少的\xe2\x80\x99。?这可以通过在模式末尾添加 来实现。

\n\n

例子:

\n\n
re.findall(\'<.*?>\', text)\n#> [\'<body>\', \'</body>\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您只想检索第一个匹配项,请改用搜索方法。

\n\n
re.search(\'<.*?>\', text).group()\n#> \'<body>\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

来源:Python 正则表达式示例

\n


Sug*_*lai 9

摘自www.regular-expressions.info

贪婪:贪婪的量词首先尝试尽可能多地重复令牌,并逐渐放弃匹配,因为引擎回溯以找到整体匹配.

懒惰:懒惰量词首先根据需要重复令牌次数,并逐渐扩展匹配,因为引擎通过正则表达式回溯以找到整体匹配.

  • 与高票答案相比,这似乎是“懒惰”最正确的定义。其他答案似乎忽略了在懒惰下引擎“逐渐扩大匹配......以找到整体匹配”的概念。 (2认同)

BKS*_*eon 8

贪婪量词就像 IRS

\n

他们\xe2\x80\x99会尽可能多地拿走。例如与此正则表达式匹配:.*

\n

$50,000

\n

再见银行余额。

\n

请参阅此处的示例:贪婪示例

\n

非贪婪量词——它们尽可能少地获取

\n

要求退税:国税局突然变得不贪婪 - 并尽可能少地退税:即他们使用这个量词:

\n

(.{2,5}?)([0-9]*)针对此输入:$50,000

\n

第一组是非需求组,仅匹配$5\xe2\x80\x93,因此我获得了$550,000 美元输入的退款。

\n

请参阅此处:非贪婪示例

\n

为什么我们需要贪婪与非贪婪?

\n

如果您尝试匹配表达式的某些部分,这一点就变得很重要。有时您不想匹配所有内容 - 尽可能少。有时您希望尽可能匹配。仅此而已。

\n

您可以尝试上面发布的链接中的示例。

\n

(用于帮助您记住的类比)。

\n


Adr*_*der 6

正则表达式

正则表达式中的标准量词是贪婪的,这意味着它们尽可能匹配,只有在必要时才返回以匹配正则表达式的其余部分.

通过使用延迟量词,表达式首先尝试最小匹配.


小智 6

最好通过例子来展示。细绳。192.168.1.1和贪婪的正则表达式\b.+\b 您可能认为这会给您第一个八位字节,但实际上与整个字符串匹配。为什么?因为.+是贪婪的,贪婪匹配会匹配其中的每个字符192.168.1.1,直到到达字符串末尾。这是重要的一点!现在它开始一次回溯一个字符,直到找到第三个标记 ( \b) 的匹配项。

如果字符串 4GB 文本文件和 192.168.1.1 位于开头,您可以很容易地看到这种回溯将如何导致问题。

要使正则表达式非贪婪(惰性),请在贪婪搜索后添加问号,例如

*?
??
+?
Run Code Online (Sandbox Code Playgroud)

现在发生的情况是标记 2 ( +?) 找到匹配项,正则表达式沿着字符移动,然后尝试下一个标记 ( \b) 而不是标记 2 ( +?)。所以它小心翼翼地爬行。


sta*_*Fan 5

贪婪意味着它会消耗你的模式,直到没有任何模式剩下,并且它无法再继续寻找。

Lazy 一旦遇到您请求的第一个模式就会停止。

我经常遇到的一个常见示例是\s*-\s*?正则表达式([0-9]{2}\s*-\s*?[0-9]{7})

第一个\s*被归类为贪婪,因为*它会在遇到数字后查找尽可能多的空格,然后查找破折号字符“-”。第二个\s*?是懒惰的,因为它的存在*?意味着它将查找第一个空白字符并停在那里。


归档时间:

查看次数:

222068 次

最近记录:

5 年,9 月 前