什么\?在正则表达式中是什么意思?

use*_*997 17 grep regular-expression

以下命令用于搜索 7 位电话号码:

grep "[[:digit:]]\{3\}[ -]\?[[:digit:]]\{4\}" file
Run Code Online (Sandbox Code Playgroud)

代表什么\?

Mik*_*kel 23

它就像?在许多其他正则表达式引擎中一样,表示“匹配零或之前的任何内容之一”。

在您的示例中, the\?应用于[ -],这意味着它尝试匹配空格或减号,但空格或减号是可选的。

因此,其中任何一个都将匹配:

555 1234
555-1234
5551234
Run Code Online (Sandbox Code Playgroud)

它被编写为\?而不是?为了向后兼容的原因。

的原始版本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.
Run Code Online (Sandbox Code Playgroud)

...

Repetition
    A regular expression may be followed by one of several repetition operators:
    ?      The preceding item is optional and matched at most once.
Run Code Online (Sandbox Code Playgroud)

...

    grep understands three different versions of regular expression syntax:
    “basic,” “extended” and “perl.”
Run Code Online (Sandbox Code Playgroud)

...

Basic vs Extended Regular Expressions
    In basic regular expressions the meta-characters ?, +, {, |, (, and )
    lose their special meaning; instead use the backslashed versions
    \?, \+, \{, \|, \(, and \).
Run Code Online (Sandbox Code Playgroud)

更多信息:


小智 9

不幸的是,正则表达式的确切语法在不同程序之间略有不同:grep 正则表达式与 sed 正则表达式不完全相同,它们与 Emacs 正则表达式不完全相同,后者与 C++ 正则表达式不完全相同,因此在。更糟糕的是,即使是像 grep 这样的“标准”工具,在不同的类 Unix 操作系统之间也可能略有不同。

在正则表达式中,某些字符具有特殊含义(例如您示例中的方括号),并且当您通过在它们前面放置反斜杠来“转义”它们时,将其恢复为正常含义作为文字字符(因此文字括号将是写成\[)。其他人则相反,只有在转义时才具有特殊含义(例如,普通 n 只是一个字母,但 \n 是换行符)。同样,这些在正则表达式实现之间可能会有所不同。

在大多数正则表达式实现中,问号表示前一项是可选的,而转义问号 (\?) 是字面问号。但在一些方言中,情况正好相反。你的例子可能有任何意义,但我怀疑你有一种方言在哪里?是文字和 \? 是可选符号。因此,您的正则表达式可能表示“三位数字,可选后跟空格或破折号,后跟四位数字”。

(另一个线索可以在像 \{3\} 这样的结构中看到,它的意思显然是“正好是前一项的 3”。在大多数正则表达式方言中,这将被写成 {3},而 \{ 将是一个文字大括号.)


Kei*_*son 6

这是其他答案中已包含的信息的快速摘要。

grep,?匹配一个文字问号字符,并\?表示它前面的任何内容的零次或一次出现。因此,在您问题的示例中,[ -]\?匹配空格、连字符或不匹配。

egrepor 中grep -E,情况正好相反;\?匹配一个字面问号,并?表示出现零次或一次。

这适用于 GNU grep;非 GNU grep 实现的细节可能略有不同。特别是,grepegrep在历史上两个独立的程序,我不觉得老grep小号有-E选项。POSIX 确实指定了grep -E,但是(我惊讶地发现)没有提到egrep.