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


16

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

grep "[[:digit:]]\{3\}[ -]\?[[:digit:]]\{4\}" file

代表什么\?

Answers:


21

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

在您的示例中,将\?应用于[ -],表示它试图匹配空格或减号,但是空格或减号是可选的。

因此,这些将匹配:

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 \).

更多信息:


egrep命令等效于grep -E。对于GNU grep以外的版本,grep可能会或可能不会接受该-E选项,并且egrep可能是单独的程序。
基思·汤普森

@KeithThompson,grep -E是POSIX的官方方式。egrep在susv2(1997)中已弃用,在susv3(2001)中从POSIX和Unix规范中删除。
斯特凡Chazelas

1
\?虽然是GNUism。
斯特凡Chazelas

8

不幸的是,正则表达式的确切语法在不同程序之间略有不同:grep regexes与sed regexes不完全相同,而sed regexes与Emacs regexes不完全相同,而Emacs regexes与C ++ regexes不完全一样,因此上。更糟糕的是,即使是类似grep的“标准”工具,在不同的类似Unix的操作系统之间也会略有不同。

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

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

(可以在\ {3 \}之类的结构中看到另一个线索,它显然是要表示“恰好是前一项的3”。在大多数正则表达式中,这将写为{3},而\ {将是一个大括号) )


6

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

中的grep?与文字问号字符匹配,并\?表示零个或一次出现的字符。因此,在您问题的示例中,[ -]\?匹配空格,连字符或什么都不匹配。

egrep或中grep -E,则相反。\?匹配文字问号,并且?表示零或一出现。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.