与grep的非贪婪匹配

jay*_*ngh 8 regex grep bsd gnu

据我所知,非贪心匹配不是基本正则表达式(BRE)和扩展正则表达式(ERE)的一部分.然而,不同版本grep(BSD和GNU)的行为似乎表明其他方面.

例如,我们来看下面的例子.我有一个字符串说:

string="hello_my_dear_polo"
Run Code Online (Sandbox Code Playgroud)

使用GNU grep:

以下是hello从字符串中提取的几次尝试.

BRE尝试:

$ grep -o "hel.*\?o" <<< "$string"
hello_my_dear_polo
Run Code Online (Sandbox Code Playgroud)

输出产生整个字符串,这表明非贪婪量词对BRE不起作用.请注意,我只是逃脱了,?因为*它没有失去意义,也不需要转义.

ERE尝试:

$ grep -oE "hel.*?o" <<< "$string"
hello_my_dear_polo
Run Code Online (Sandbox Code Playgroud)

启用该-E选项也会产生相同的输出,表明非贪婪匹配不是ERE的一部分.由于我们使用ERE,因此不需要转义.

PCRE尝试:

$ grep -oP "hel.*?o" <<< "$string"
hello
Run Code Online (Sandbox Code Playgroud)

启用-PPCRE选项表明非贪婪量词是其中的一部分,因此我们得到了所需的输出hello.由于我们使用PCRE,因此不需要转义.

使用BSD grep:

以下是hello从字符串中提取的几次尝试.

BRE尝试:

$ grep -o "hel.*\?o" <<< "$string"
Run Code Online (Sandbox Code Playgroud)

使用BRE我没有得到BSD的输出grep.

ERE尝试:

$ grep -oE "hel.*?o" <<< "$string"
hello
Run Code Online (Sandbox Code Playgroud)

启用该-E选项后,我很惊讶我能够提取所需的输出.我的问题是我从这次尝试得到的输出.

PCRE尝试:

$ grep -oP "hel.*?o" <<< "$string"
usage: grep [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
    [-e pattern] [-f file] [--binary-files=value] [--color=when]
    [--context[=num]] [--directories=action] [--label] [--line-buffered]
    [--null] [pattern] [file ...]
Run Code Online (Sandbox Code Playgroud)

使用-P选项给了我使用错误,这是预期的,因为BSD选项grep不支持PCRE.

所以我的问题是为什么在BSD上使用ERE会grep产生使用非贪婪量词但不使用GNU的正确输出grep.

这是一个错误,BSD的未记录功能egrep还是我对输出的错误理解?

tri*_*eee 2

双量词只是一个语法错误,可能会导致错误消息或未定义的行为。如果您收到错误消息,这可能会更好。

Perl 对 POSIX 后的正则表达式进行了大幅扩展;在编写这些工具时,极不可能有人尝试使用这种古怪的语法来做任何事情。贪婪匹配仅在 20 世纪 90 年代中期的 Perl 5 中引入。