返回首页 两个月精通 Shell 脚本

shell 学习第八天----扩展正则表达式 (ERE)

扩展正则表达式 (ERE)

拥有笔记本正则表达式更多的功能。BRE 与 ERE 在大多数的 meta 字符与功能应用上几乎是完全一致,单 ERE 理由写 meta 字符看起来与 BRE 类似,却具有完全不同的类型。

扩展正则表达式与基础正则表达式的唯一区别在于:? + () {} 这几个字符。基础正则表达式中,如果你想? + () {} 表示特殊含义,你需要将他们转义。而扩展正则表达式中,如果你想? + () {} 不表示特殊含义,你需要将他们转义。转义符号,都是一样的,\ 符号。

所谓特殊含义,就是正则表达式中的含义。非特殊含义,就是这个符号本身。

例如

  • [root@shellcn.net ~#] echo aaa|grep 'a?';[root@shellcn.net ~#] echo aaa|grep 'a\?';aaa#egrep 使用的是扩展正则表达式
  • [root@shellcn.net ~#] echo aaa|egrep 'a?';aaa[root@shellcn.net ~#] echo aaa|egrep 'a\?';

可见,扩展正则表达式与基础正则表达式的区别,就是它们加不加转义符号,代表的意思刚好相反。

ERE 历史没有后向引用的。圆括号在 ERE 里具有特殊含义,但和 BRE 里使用的又有所不同。在 ERE 里,\ ( 与 \ ) 匹配的是字面上的左括号与右括号。

匹配单个表达式与多个正则表达式

ERE 在匹配多字符这方面,与 BRE 有明显的不同,不过在 (*) 的处理上和 BRE 是相同的。

注意:

  • 有一个例外,* 作为 ERE 的第一个字符是” 未定义的”,而在 BRE 中它是指” 符合字面的”。
  • 一般情况下使用 grep 控制 BRE,使用 egrep 控制 ERE。
  • 使用 ERE 匹配我们之前介绍过的离子” 要刚好重现 5 个 a” 以及” 重现 10 个至 42 个 q”,写法分别为:a{5},q{10,42}。而 {与 } 则可以匹配字面上的花括号。当在 ERE 里 {找不到匹配} 时,POSIX 特意保留其含义为” 未定义状态”。

ERE 另有两个 meta 字符,可更细腻的处理匹配控制:

  • ? 匹配于 0 个或一个前置正则表达式
  • + 匹配于一个或多个前置正则表达式

可以把? 想象成是” 可选用的”,也就是说,匹配前置正则表达式的文本,要么出现,要么没出现。例如: 与 ab?c 匹配的有 ac 与 abc,就这两者 ! (与 ab*c 相较之下,后者匹配于中间有人一个 b)。

+ 字符在概念上与 *meta 字符类似,不过前置正则表达式要匹配的文本在这里至少得出现一次。例如 ab+c 匹配于 abc,abbc,abbbc,但是不匹配于 ac。ab+c 的正则表达式等价于 abbc; 无论如何,当前值正则表达式很复杂时,使用 + 可以少打一点字,这就减少了打错字的几率。

交替

方括号运算符一宇表示” 匹配于次祖父,或其他字符,或...”,但不能指定” 匹配于这个序列,或其他序列”。要达到后者的目的,可以使用管道运算符 (|)。例如 read | write 匹配于 read 与 write 两者,fast|slow 匹配于 fast 与 slow。| 字符是 ERE 运算符;i 优先级最低的。