据我所知,非贪心匹配不是基本正则表达式(BRE)和扩展正则表达式(ERE)的一部分。然而,不同版本的grep
(BSD和GNU)的行为似乎暗示其他方面。
例如,我们来看下面的例子。我有一个字符串说:
string="hello_my_dear_polo"
grep
:以下几次尝试从字符串中提取hello
。
BRE尝试(失败):
$ grep -o "hel.*\?o" <<< "$string"
hello_my_dear_polo
输出产生整个字符串,这表明非贪婪量词对BRE不起作用。请注意,我只逃脱了?
,因为*
没有失去它的含义,也不需要逃脱。
ERE尝试(失败):
$ grep -oE "hel.*?o" <<< "$string"
hello_my_dear_polo
启用-E
选项也会产生相同的输出,表明非贪婪匹配不是ERE的一部分。由于我们使用ERE,因此不需要转义。
PCRE尝试(成功):
$ grep -oP "hel.*?o" <<< "$string"
hello
为PCRE启用-P
选项表明非贪婪量词是其中的一部分,因此我们得到所需的hello
输出。由于我们使用PCRE,因此不需要转义。
grep
:以下是从字符串中提取hello
的几次尝试。
BRE尝试(失败):
$ grep -o "hel.*\?o" <<< "$string"
使用BRE我得不到BSD grep
的输出。
ERE尝试(成功):
$ grep -oE "hel.*?o" <<< "$string"
hello
启用-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 ...]
使用-P
选项给了我使用错误,这是预期的,因为grep
的BSD选项不支持PCRE。
所以我的问题是为什么在BSD grep
上使用ERE会使用非贪婪量词而不是GNU grep
产生正确的输出。
这是一个错误,BSD egrep
没有记录的功能或我对输出的误解?
双量词只是一个语法错误,可能导致错误消息或未定义的行为。如果您收到错误消息,可能会更好。
Perl对正则表达式后日期POSIX的扩展很大;在编写这些工具时,人们极不可能尝试将这种古怪的语法用于任何事情。贪婪匹配仅在20世纪90年代中期在Perl 5中引入。