在 ERE 里,我们已经提到运算符是被应用到“前置的正则表达式”。这是因为圆括号 (...) 提供分组功能,让接下来的运算符可以应用。举例来说,(why)+ 匹配于一个连续重复的多个 why 。
在必须用到交替时, 分组的功能就特别好用(也是必须的)。它可以让你用以构建复杂并灵活的正则表达式。 [Tt]he (CPU|computer) is 指的就是:在 The (the)与 is 之间,含有 CPU 或 computer 的句子。要特别注意的一点是,圆括号在这里是 meta 字符,而非要匹配的输入文本。
将重复运算符与交替功能结合时,分组功能也是一定用得到的。 read|write+指的是正好一个 read ,或是一个 write 后面接着任意数个 e 字符,比较有用的模式应该是 (read|write)+,它指的是:有一个或重现多个 read ,或者一个或重现多个 write 。
当然,(read|write)+ 所指的字符串中间,不允许有空白。((read|write)[[:space:]*])+ 的正则表达式看起来虽然比较复杂,不过也比较实际些。乍看之下,这可能会搞不清,不过若把这些组成部分分隔开来看,其实就不难理解。
结论就是:这个单个正则表达式是用以匹配多个连续出现的 read 或是 write,且中间可能被空白字符隔开。
在 [[:space:]] 之后使用 * 是一种判断调用。使用一个 * 而非 + ,此匹配可以取得在行(或字符串)结尾的单词。但也可能可以匹配中间完全没有空白的单词。 运用正则表达式时常会需要用到这样的判断调用。该如何构建正则表达式,需要根据输入的数据以及这些数据的用途而定。
最后要说的是:将交替操作结合 ^ 与 $ 锚点字符使用时,分组就非常好用了。由于 | 为所有运算符中优先级最低的,因此正则表达式 ^abcd|efgh$意思是“匹配字符串的起始处是否有 a b c d 或者字符串结尾处是否有 e f g h ”。这和 ^(abcd|efgh)$ 不一样,后者表示的是“找一个正是abcd或正是efgh的字符串”。