与grep的非贪婪匹配

时间:2014-05-04 08:32:39

标签: regex grep gnu bsd

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

例如,让我们举几个例子。我有一个字符串说:

string="hello_my_dear_polo"

使用GNU grep

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

BRE尝试(失败)

$ grep -o "hel.*\?o" <<< "$string"
hello_my_dear_polo

输出产生整个字符串,表明非贪婪量词对BRE不起作用。请注意,由于? *没有丢失它的含义而且无需转义,因此我只转义了$ grep -oE "hel.*?o" <<< "$string" hello_my_dear_polo

ERE尝试(失败)

-E

启用$ grep -oP "hel.*?o" <<< "$string" hello 选项也会产生相同的输出,表明非贪婪匹配不是ERE的一部分。由于我们使用的是ERE,因此不需要转义。

PCRE尝试(成功)

-P

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

使用BSD hello

以下是从字符串中提取$ grep -o "hel.*\?o" <<< "$string" 的几次尝试。

BRE尝试(失败)

grep

使用BRE我没有得到BSD $ grep -oE "hel.*?o" <<< "$string" hello 的输出。

ERE尝试(成功)

-E

启用$ 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 ...] 选项后,我感到惊讶我能够提取所需的输出。 我的问题是我从这次尝试中获得的输出。

PCRE尝试(失败)

-P

使用grep选项给出了我的预期使用错误,因为grep的BSD选项不支持PCRE。

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

这是一个错误,BSD {{1}}没有记录的功能还是我对输出的误解?

1 个答案:

答案 0 :(得分:2)

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

Perl对regex post-date POSIX的扩展很大;在编写这些工具时,人们极不可能尝试将这种古怪的语法用于任何事情。贪婪匹配仅在20世纪90年代中期在Perl 5中引入。