grep 的 matcher 说明

在使用 grep 时涉及正则表达式的编写,不同的 matcher 使用不同的正则表达式语法。为避免混淆,阅读 man grep,对几种 matcher 作简要说明。

  • 匹配器 matcher 分类

    grep -E: extented regular expression(ERE)
    grep -F: fixed strings,固定字符串,不作正则表达式处理,只按字面处理
    grep -G: basic regular expression(BRE)
    grep -P: perl-compatible regular expression(PCRE)
    grep 支持 3 种匹配器,能识别 3 种正则表达式语法:ERE、BRE、PCRE,其中 PCRE 语法需要预先在操作系统中安装PCRE
    gnu grep ERE、BRE 语法的功能实现相同,即 grep -Egrep -G 没有区别,不带参数的调用 grep 可认为使用 ERE matcher
    gnu grep ERE、BRE 的功能实现可能不同,BRE 的功能稍弱
  • ERE 正则表达式语法

    • 基本规则

      1, 定义:正则表达式是一个模式 pattern*,它描述了一组字符串,这些字符串具备该模式所描述的特征。正则表达式由多个更小的正则表达式组合而成。
      2, 正则表达式的基础单元 *fundamental building blocks
      是匹配单个字符的正则表达式。由单个字符组成的正则表达式,匹配该字符本身(大多数情况下)
      3, 元字符 meta-character 在正则表达式中具有特殊意义,在前面使用反斜杠 \ 使其做为普通字符。
      4, 正则表达式 点 . 匹配任意 单个 字符
    • [] 表达式与字符分类

      1, [] 表达式表示:匹配中括号内任意 单个 字符
      在 [] 中可使用范围表达式,如 [a-d1-3] = [abcd123]。需要注意的是,范围表达式中,字符的排序与操作系统当前的 locale 设置有关,[a-d] 有可能= [aBbCcDd]。要想得到一致的字符范围结果,可把 LC_ALL 环境变量设置为 C,即 export LC_ALL=C
      2, [^] 否定集:匹配 在列表内的任意 单个 字符
      3, [] 预定义了一些字符分类 classes,简化正则表达式的书写。
    [:alnum:] :字母 letters 和数字 numbers
    [:alpha:] :字母
    [:cntrl:] :控制字符
    [:digit:] :数字,十进制
    [:graph:] :非空白字符
    [:lower:] :小写字母
    [:print:] :可打印字符
    [:punct:] :标点符号
    [:space:] :空格符
    [:upper:] :大写字母
    [:xdigit:] :数字,十六进制
    需要注意的是,字符分类中的方括号是字符分类的一部分,使用时需再用一对方括号括起来,例如:[[:digit:]]
    4, 中括号里的元字符大部分会失去其特殊的意义。部分元字符可能会影响正常的正则表达式解析,可调整字符位置进行规避,如 ^ 不放首位,\] 放首位,- 放末位
    • Anchoring 定位

      1, 行 line 匹配定位
      ^ 匹配一行开头的空字符串 empty string at the beginning of a line
      $ 匹配一行结束的空字符串 empty string at the end of a line
      正则表达式:^a 可理解为匹配首字符为 a 的行
      正则表达式:b$ 可理解为匹配末字符为 b 的行
      2, 词 word 匹配定位(反斜杠的使用)
      \< 匹配一个词开头的空字符串 empty string at the beginning of a word
      \> 匹配一个词结束的空字符串 empty string at the end of a word
      \b 匹配一个词两端的空字符串 empty string at the edge of a word
      \B 匹配不在词两端的空字符串 empty string not at the edge of a word
    • 反斜杠的特殊表达

      除上一节中 \< \> \b \B
      \w = [_[:alnum:]]:下划线和字母和数字
      \W = [^_[:alnum]]:非(下划线和字母和数字)
    • 重复 repetition

      前导 precedence 后,可紧跟重复操作符,表示重复匹配前导所组成的正则表达式
      ? 匹配最多 1 次
      * 匹配 0 次或更多
      + 匹配 1 次或更多
      {n} 精确匹配 n 次
      {n,} 匹配 n 次或更多
      {,m} 匹配最多 m 次(仅 gnu grep 可用)
      {n,m} 匹配最少 n 次, 最多 m 次
    • 连接 concatenation

      两个正则表达式可连接形成新的正则表达式,匹配新正则表达式的字符串可分为两个子串,两个子串分别匹配原两个正则表达式。
      可理解为:多个正则表达式可任意组合(结合 基本规则正则表达式的基础单元 一起理解)
    • 交替 alternation

      操作符 | 连接两个正则表达式, A|B 表示匹配正则表达式 AB
    • 前导 precedence

      前面提到,重复 符重复匹配 前导,那么匹配器如何判断 前导 呢?
      判断前导:重复 repetition 使用 连接 concatenation 判断前导,进而使用 交替 alternation 判断前导
      改变前导规则:括号。使用括号后,将产生子表达式 subexpression
    • 向后参考 back reference 和子表达式 subexpression

      向后参考语法:\nn 是单个数字,表示一个子字符串,该字符串匹配之前匹配的第 n 个子表达式。
      正则表达式中括号内的内容是该正则表达式的子表达式。
    • BRE 与 ERE 区别

      BRE 中,部分 meta-character 失去特殊意义,要想使用特殊意义,需要在元字符前加反斜杠,如:\? \+ \{ \} \| \( \)
    • locale 信息检测

      环境变量检测顺序:LC_ALLLC_XXXLANG,如果这些环境变量都没有设置,则把当前 locale 设置为 C
      查看已安装的locale:locale -a
      设置当前locale:export LC_foo="bar"
  • PCRE 正则表达式语法
    略。