我对grep似乎解析正则表达式的方式感到非常困惑:
$ echo "@NS500287" | grep '^@NS500[0-9]{3}'
#nothing
$ echo "@NS500287" | grep '^@NS500[0-9]\{3\}'
@NS500287
这不可能是正确的。为什么我要转义大括号,它是“匹配前一个,N次”组件的一部分(而不是,例如方括号)?
只有当我在查询字符串中编写一个实际上与{
和}
匹配的正则表达式时才应该转义吗?
更多的 cri de coeur 比其他任何事情更多,但我对答案感到好奇。
答案 0 :(得分:14)
这是因为{}
是特殊字符,需要以不同方式处理才能具有此特殊行为。否则,它们将被视为文字{
和}
。
你可以像你一样逃避:
$ 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,见下文)。 (-E由POSIX指定。)
...
正常表达
正则表达式是描述一组字符串的模式。 正则表达式的构造类似于算术 表达式,通过使用各种运算符来组合较小的 表达式。
grep了解正则表达式的三种不同版本 语法:“基本”,“扩展”和“perl。”在GNU grep中,有 基本和扩展之间的可用功能没有区别 语法。在其他实现中,基本正则表达式是 不那么强大。以下描述适用于扩展常规 表达式;总结了基本正则表达式的差异 然后。 Perl正则表达式提供了额外的功能, 并记录在pcresyntax(3)和pcrepattern(3)中,但可能不是 可在每个系统上使用。
...
基本与扩展正则表达式
在基本正则表达式中,元字符?,+,{,|,(和)失去了它们的特殊含义;而是使用反斜杠版本
\?
,\+
,\{
,\|
,\(
和\)
。
答案 1 :(得分:6)
答案与基本正则表达式(BRE)和扩展正则表达式(ERE)之间的区别有关。
在BRE模式下(即当您调用grep时没有参数指定其他情况),{
和}
被解释为文字字符。使用\
转义它们意味着它们将被解释为先前模式的多个实例。
如果您使用grep -E
代替(ERE模式),您可以使用{
和}
而无需转义以引用计数。在ERE模式下,转义大括号会导致它们被字面解释。
答案 2 :(得分:0)
取而代之的是
echo '@NS500287' | egrep '^@NS500[0-9]{3}'
# ^
# /
# notice ---