正则表达式“.*?”与“.*”输出相同

正则表达式“.*?”与“.*”输出相同

这是我正在使用的文件:

Shane 有点不擅长打球
小的
愚蠢的

当我使用

egrep 's.*l' new

我得到的输出为

谢恩玩一点球
小的
窗台

当我使用

egrep 's.*?l' new

我得到了与上面相同的输出,但它应该是不同的。

答案1

尽管你说“应该有所不同”你忽略了说明你期望的输出。据我所知,正?则表达式中的可能解释是:

  • 在一个基本正则表达式 (BRE)?是一个文字问号;由于您的输入不包含这样的字符,因此的输出grep 's.*?l' new将为空。

  • 在一个扩展正则表达式 (ERE)?量词表示零个或一个前一个正则表达式原子。在这种情况下,.*?表示“零个或多个单个字符(.*),重复零次或一次(?)” - 这相当于.*,因此egrep 's.*?l'egrep 's.*l'将产生相同的输出。

  • 在一个perl 兼容正则表达式 (PCRE)?是贪婪修饰符,这样.*?s.*?l匹配最短之间的字符序列s,而l贪婪s.*l匹配最长这样的顺序。因此

    $ grep -P 's.*?l' new
    Shane is a little to play ball
           ^^^^^
    

    尽管

    $ grep -E 's.*?l' new
    Shane is a little to play ball
           ^^^^^^^^^^^^^^^^^^^^^^^
    

?对于简单的情况,你可以通过使用否定字符集来实现不使用 PCRE 修饰符的“惰性” 。

grep 's[^l]*l' new

s匹配除以下字符之外的任何字符 l, 其次是l


旁白:从技术上来说已被弃用 - 您应该养成使用BRE、ERE 和PCREegrep的习惯。grepgrep -Egrep -P

答案2

简单来说,有 POSIX 正则表达式,然后有各种扩展,例如 Perl 兼容正则表达式 (PCRE),它们在多种语言中实现(不仅仅是 Perl)。非贪婪修饰符 *? 是特定于 PCRE 的扩展。在 POSIX 正则表达式中,它没有任何特殊含义,它只会将 ? 视为多余的。

在 grep 中,您可以使用命令行修饰符轻松切换到 PCRE 模式-P

相关内容