![为什么 grep 要求在加号前加上反斜杠才能将加号视为量词?](https://linux22.com/image/1049019/%E4%B8%BA%E4%BB%80%E4%B9%88%20grep%20%E8%A6%81%E6%B1%82%E5%9C%A8%E5%8A%A0%E5%8F%B7%E5%89%8D%E5%8A%A0%E4%B8%8A%E5%8F%8D%E6%96%9C%E6%9D%A0%E6%89%8D%E8%83%BD%E5%B0%86%E5%8A%A0%E5%8F%B7%E8%A7%86%E4%B8%BA%E9%87%8F%E8%AF%8D%EF%BC%9F.png)
我想尝试一下grep
使用正则表达式的命令,但发现它们的行为与我的预期不同。例如,考虑temp
具有以下内容的文件
helloworld
hello_world
hello world
hello how are you world
hello wor ld
hello_*_..world
helloEworld
当我跑步的时候
grep 'hello.*world' temp
它返回
helloworld
hello_world
hello world
hello how are you world
hello_*_..world
helloEworld
正如预期的那样。但是当我运行
grep 'hello.+world' temp
它什么也没有返回...尽管我\
之前添加+
grep 'hello.\+world' temp
它返回正确的输出
hello_world
hello world
hello how are you world
hello_*_..world
helloEworld
在上一个命令\
之前添加并运行*
grep 'hello.\*world' temp
什么也没返回...
为什么没有 ,grep 'hello.+world' temp
命令就不起作用\
?
为什么 恰恰相反*
?
我什么时候应该使用\
?
答案1
GNU 支持多种类别的正则表达式grep
:
基本正则表达式 (BRE) - 默认。不直接支持
+
,但支持。转义后,*
您可以使其有意义。来自+
\+
GNU grep 文档:In basic regular expressions the meta-characters ‘?’, ‘+’, ‘{’, ‘|’, ‘(’, and ‘)’ lose their special meaning; instead use the backslashed versions ‘\?’, ‘\+’, ‘\{’, ‘\|’, ‘\(’, and ‘\)’.
扩展正则表达式 (ERE) - 该选项
-E
启用此功能。直接支持+
和*
。- Perl 兼容正则表达式 (PCRE) - 该
-P
选项启用 PCRE。支持与 Perl 类似的语法,例如前瞻和后瞻。
BRE 和 ERE 通常POSIX 定义的标准类,因此您应该在任何grep
渴望实现 POSIX 兼容性的地方找到它们,并期望它们有类似的行为。