如何或为什么使用`.*?` 比`.*` 更好?

C0d*_*lus 11 regular-expression wildcards

在 SuperUser 上回答了这个问题,该问题与 grepping 输出时使用的正则表达式类型有关。

我给出的答案是这样的:

 tail -f log | grep "some_string.*some_string"
Run Code Online (Sandbox Code Playgroud)

然后,在对我的回答@Bob 的三个评论中写道:

.*是贪婪的,可能会捕获比您想要的更多。.*?通常更好。

那么这个,

?是 上的修饰符*,使其变得懒惰而不是贪婪的默认值。假设 PCRE。

我用谷歌搜索PCRE,但无法在我的答案中得到这有什么意义?

最后这个,

我还应该指出这是正则表达式(默认情况下 grep 执行 POSIX 正则表达式),而不是 shell glob。

我只知道 Regex 是什么以及它在 grep 命令中的基本用法。所以,我无法得到这 3 条评论中的任何一条,我有这些问题:

  • .*?vs. 的用法有什么区别.*
  • 在什么情况下哪个更好?请举例说明。

理解评论也会有帮助,如果有人可以的话


更新:作为问题的答案Regex 与 Shell Globs 有何不同? @Kusalananda在他的评论中提供了这个链接

注意:如果需要,请在回答参考上下文之前阅读我对这个问题的回答。

Ash*_*ora 10

假设我使用一个字符串:

can cats eat plants?

使用 greedyc.*s将匹配整个字符串,因为它以 开头c和结尾s,作为一个贪心运算符,它会继续匹配直到最后出现 s。

而使用 lazyc.*?s只会匹配,直到s找到第一次出现的,即 string can cats

从上面的示例中,您可能会发现:

“贪婪”意味着匹配最长的字符串。“懒惰”意味着匹配最短的字符串。将 a 添加?到像*, +, 之类的量词上?,或者{n,m}使它变得懒惰。

  • @Kusalananda 是真的,不是严格意义上的,而是“最短可能”在这里是指第一次出现 c 和 s 之间。 (3认同)

nxn*_*nev 9

阿肖克已经指出的区别.*.*?,所以我就提供一些额外的信息。

grep (假设为 GNU 版本)支持 4 种匹配字符串的方式:

  • 固定字符串,带-F选项
  • 基本正则表达式 (BRE),默认
  • 扩展正则表达式 (ERE),带有-E选项
  • Perl 兼容的正则表达式 (PCRE),带有-PGNU grep 中的选项

grep 默认使用 BRE。

BRE 和 ERE 记录在POSIX的正则表达式一章中,PCRE 记录在其官方网站中。请注意,功能和语法可能因实现而异。

值得一提的是,BRE 和 ERE 都不支持懒惰

多个相邻重复符号(“+”、“*”、“?”和间隔)的行为会产生未定义的结果。

因此,如果您想使用该功能,则需要改用 PCRE:

# PCRE greedy
$ grep -P -o 'c.*s' <<< 'can cats eat plants?'
can cats eat plants

# PCRE lazy
$ grep -P -o 'c.*?s' <<< 'can cats eat plants?'
can cats
Run Code Online (Sandbox Code Playgroud)

你能解释一下.*vs.*?吗?

  • .*用于匹配可能的“最长” 1模式。

  • .*?用于匹配可能的“最短” 1模式。

根据我的经验,最想要的行为通常是第二个。

例如,假设我们有以下字符串,我们只想匹配 html 标签2,而不是它们之间的内容:

<title>My webpage title</title>
Run Code Online (Sandbox Code Playgroud)

现在比较.*vs .*?

# Greedy
$ grep -P -o '<.*>' <<< '<title>My webpage title</title>'
<title>My webpage title</title>

# Lazy
$ grep -P -o '<.*?>' <<< '<title>My webpage title</title>'
<title>
</title>
Run Code Online (Sandbox Code Playgroud)

1.正如 Kusalananda 指出的那样,正则表达式上下文中“最长”和“最短”的含义有点棘手。有关更多信息,请参阅官方文档。
2.不建议用regex解析html。这只是一个用于教育目的的例子,不要在生产中使用它。