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

shell 学习第九天----分组

分组

基本正则表达式中支持分组,而在扩展正则表达式中,分组的功能更加强大,也可以说才是真正的分组,用法如下:

():分组,后面可以使用 \1 \2 \3... 引用前面的分组,除了方便后面引用外,分组还非常方便的可以使用上述次数匹配方法进行匹配具有相同条件的数据。

如:grep '^(barlow).*\1' /etc/passwd 搜索 /etc/passwd 中以 barlow 开头,而后面还存在 barlow 的行。

在 BRE 中,我们使用一些 meta 字符修饰前置字符,匹配重复的情况。但是这样的操作仅仅针对单个字符。在 ERE 中,分组功能能够计 meta 字符修饰前置字符串。一个针对字符,一个针对字符串。

在 ERE 里,我么已经提到运算符是被应用到” 前置的正则表达式”。这是因为有圆方括号 ({...}) 提供分组功能,让接下来的运算符可以应用。例如 (why)+ 匹配于一个或连续重复的多个 why。再例如:[Tt]he (CPU|computer) is 指的是: 在 the(The) 与 is 之间,含有 CPU 或 computer 的句子。特别注意: 圆括号里的是 meta 字符,而非要匹配的输入文本。由此看出用到交替的时候,分组特别有用。

例如 (read|write)+ 指的是: 有一个或重现多个 read,或者一个或重现多个 write.(read|write)+ 所指的字符串中间,不允许有空白。当将交替操作结合 ^ 与 $ 锚点字符使用时,分组就非常好用了。由于 | 为所有运算符中优先级最低的,因此正则表达式 ^abcd|efgh$ 意思是” 匹配字符串的起始处是否具有 a b c d 或者字符串结尾是否具有 e f g h”(表示查找字符),这和 ^(abcd)|(efgh)$ 不一样,后者的意思是” 找一个正好是 abcd 或正好是 efgh 的字符串”

停驻文本匹配 (锚点)

  • “^” 与”$” 在 ERE 和 BRE 表示的含义是相同的,需要注意的是他们在方括号表达式中将会失去他们的特殊意义;
  • 组合使用,例如 this is ^(one|two)$ 匹配 one 或者 two。在 ERE 里,^$ 永远是 meta 字符。所以,像 ab^cdef$gh 这样的正则表达式仍然是有效的,只是无法匹配到任何东西,因为 ^ 前面有其他的字符串,$ 后面也有字符串,失去了他们的特殊含义。

ERE 运算符的优先级

运算符
含义
[..]  [= =]  [:  :]
用于字符对应的方括号符号
\metacharacter
转移的 meta 字符
[]
方括号表达式 
()
分组
*  +  ?  {}
重复潜质的正则表达式
无符号 (no symbol)
连续字符
^    $
锚点
|
交替

正则表达式的扩展

最常见的扩展为 \<\> 运算符, 分别匹配” 单词 (word)” 的开头与结尾, 单词是由字母, 数字及下划线组成的。我们称这类字符为单词组成。

例如:\<chop 匹配于 use chopsticks,但是 eat a lambchop 则不匹配;同样的 chop>\ 匹配与第二个字符串,第一个则不匹配。特别注意\<chop>\ 的表达式下,两个字符串都不匹配。

额外的 GNU 正则运算符

运算符
含义
\w
匹配任何单词组成字符
\W
匹配任何非单词组成字符
\<\>
匹配单词的起始和结尾
\b
匹配单的起始或结尾处所找到的空字符串 / 这是 \< 与 >\ 运算符的结合. 注意: 由于 awk 使用 \b 表示后退运算符, 因此 GNU awk(gawk) 使用 \y 表示此功能。
\B
匹配两个单词组成字符之间的空字符串
\’ \ `
分别匹配 emacs 缓冲区的开始与结尾.GNU 程序 (wmacs) 通常将他们是位 ^ 和 $ 同义。

例子:'<!-\?[^-]\+'#< 后面是 ! 然后是 0~1 个-,最后是一个非-字符。