Answers:
就像?
在许多其他正则表达式引擎中一样,它的意思是“匹配零或之前匹配的任何一个”。
在您的示例中,将\?
应用于[ -]
,表示它试图匹配空格或减号,但是空格或减号是可选的。
因此,这些将匹配:
555 1234
555-1234
5551234
它写为的原因 \?
而不是?
为了向后兼容。
原始版本 grep
使用了另一种类型的正则表达式,称为“基本正则表达式”,其中?
仅表示文字问号。
为了使GNU grep可以具有零个或一个功能,他们添加了它,但必须使用 \?
语法,以便所脚本?
仍能按预期工作。
请注意,grep有一个 -E
选项,使其可以使用更常见的正则表达式类型,称为“扩展正则表达式”。
man 1 grep
:
-E, --extended-regexp
Interpret PATTERN as an extended regular expression
(ERE, see below). (-E is specified by POSIX.)
-G, --basic-regexp
Interpret PATTERN as a basic regular expression (BRE, see below).
This is the default.
...
Repetition
A regular expression may be followed by one of several repetition operators:
? The preceding item is optional and matched at most once.
...
grep understands three different versions of regular expression syntax:
“basic,” “extended” and “perl.”
...
Basic vs Extended Regular Expressions
In basic regular expressions the meta-characters ?, +, {, |, (, and )
lose their special meaning; instead use the backslashed versions
\?, \+, \{, \|, \(, and \).
更多信息:
grep -E
选项和 egrep
grep -E
是POSIX的官方方式。egrep
在susv2(1997)中已弃用,在susv3(2001)中从POSIX和Unix规范中删除。
\?
虽然是GNUism。
不幸的是,正则表达式的确切语法在不同程序之间略有不同:grep regexes与sed regexes不完全相同,而sed regexes与Emacs regexes不完全相同,而Emacs regexes与C ++ regexes不完全一样,因此上。更糟糕的是,即使是类似grep的“标准”工具,在不同的类似Unix的操作系统之间也会略有不同。
在正则表达式中,某些字符具有特殊含义(例如,示例中的方括号),并且当您通过在其前面加上反斜杠“转义”它们时,将其恢复为普通字符,即原义字符。写为\ [)。其他人则以相反的方式工作,并且只有在转义时才具有特殊含义(例如,普通n只是一个字母,而\ n是换行符)。同样,这些可能在正则表达式实现之间有所不同。
在大多数正则表达式实现中,问号表示前一项是可选的,而转义的问号(\?)是文字问号。但是在一些方言中,情况恰恰相反。您的示例在任何一种情况下都可以理解,但是我怀疑您的方言之一在哪里?是文字和\?是可选符号。因此,您的正则表达式可能表示“三位数,可以选择后面跟一个空格或破折号,再跟四位数”。
(可以在\ {3 \}之类的结构中看到另一个线索,它显然是要表示“恰好是前一项的3”。在大多数正则表达式中,这将写为{3},而\ {将是一个大括号) )
egrep
命令等效于grep -E
。对于GNU grep以外的版本,grep
可能会或可能不会接受该-E
选项,并且egrep
可能是单独的程序。