我对grep解析正则表达式的方式感到非常困惑:
$ echo "@NS500287" | grep '^@NS500[0-9]{3}'
#nothing
$ echo "@NS500287" | grep '^@NS500[0-9]\{3\}'
@NS500287
这不对吧。为什么我需要转义花括号,而不是方括号等作为“匹配前面的N次”组件的一部分时呢?
难道只有当我编写一个实际匹配查询字符串中的 {
和 }
字符的正则表达式时才需要转义吗?
这更像是情感宣泄,但我很好奇答案。
我对grep解析正则表达式的方式感到非常困惑:
$ echo "@NS500287" | grep '^@NS500[0-9]{3}'
#nothing
$ echo "@NS500287" | grep '^@NS500[0-9]\{3\}'
@NS500287
这不对吧。为什么我需要转义花括号,而不是方括号等作为“匹配前面的N次”组件的一部分时呢?
难道只有当我编写一个实际匹配查询字符串中的 {
和 }
字符的正则表达式时才需要转义吗?
这更像是情感宣泄,但我很好奇答案。
这是因为 {}
是特殊字符,需要以不同的方式处理才能具有这种特殊行为。否则,它们将被视为字面上的 {
和 }
。
你可以像你所做的那样进行转义:
$ echo "@NS500287" | grep '^@NS500[0-9]\{3\}'
@NS500287
或者使用 grep -E
:
$ echo "@NS500287" | grep -E '^@NS500[0-9]{3}'
@NS500287
未经任何处理:
$ echo "he{llo" | grep "{"
he{llo
从man grep
:
-E,--extended-regexp
将PATTERN解释为扩展正则表达式(ERE,见下文)。(POSIX规定了-E。)
...
正则表达式
正则表达式是描述一组字符串的模式。正则表达式类似于算术表达式,通过使用各种运算符来组合较小的表达式来构造。
grep理解三种不同版本的正则表达式语法:“基本”,“扩展”和“perl”。在GNU grep中,基本和扩展语法之间没有可用功能上的区别。在其他实现中,基本正则表达式的功能较弱。下面的描述适用于扩展正则表达式;基本正则表达式的差异在后面总结。Perl正则表达式提供额外的功能,并在pcresyntax(3)和pcrepattern(3)中进行了记录,但可能不适用于每个系统。
...
基本正则表达式与扩展正则表达式
在基本正则表达式中,元字符“?”,“+”,“{”,“|”,“(”和“)”失去其特殊含义;而需要使用反斜杠版本
\?
,\+
,\{
,\|
,\(
和\)
。
在BRE模式下(即在调用grep而不指定其他参数时),{
和}
会被解释为字面字符。通过使用\
来转义它们,这意味着它们应该被解释为前一个模式的实例数。
如果您改用grep -E
(ERE模式),则可以使用{
和}
而无需转义来引用计数。在ERE模式下,转义大括号会导致它们被解释为字面量。
echo '@NS500287' | egrep '^@NS500[0-9]{3}'
# ^
# /
# notice ---