在认识了 char. set 这个概念后, 然后再让我们多认识几个 RE 中常见的 meta 字符

 

- 锚点(anchor) 

用以标识 RE 于句子中的位置所在. 常见有

^: 表示句首. ^abc 表示以 abc 开首的句子

$: 表示句尾. abc$ 表示以 abc 结尾的句子

\<: 表示词首. \<abc 表示以 abc 开首的词

\>: 表示词尾. abc\> 表示以 abc 结尾的词

 

- 修饰字符(modifier) 

独立表示时本身不具意义, 专门用以修改前一个 char. set 的出现次数. 常见有

*: 表示前一个 char. set 的出现次数为 0 或多次. ab*c 表示 a c 之间可有 0 或多

b 存在

?: 表示前一个 char. set 的出现次数为 0 1 . ab?c 表示 a c 之间可有 0

1 b 存在

+: 表示前一个 char. set 的出现次数为 1 或多次. ab+c 表示 a c 之间可有 1

多个 b 存在

{n}: 表示前一个 char. set 的出现次数必须为 n . ab{3,}c 表示 a c 之间必须

3 b 存在.{n,}: 表示前一个 char. set 的出现次数至少为 n . ab{3,}c 表示

a c 之间至少有 3 b 存在

{n,m}: 表示前一个 char. set 的出现次数为 n m . ab{3,5}c 表示 a c

间有 3 5 b 存在

 

然而, 当我们在识别 modifier , 却很容易忽略"边界(boundary)"字符的重要性

以刚提到的 ab{3,5}c 为例, 这里的 a c 就是边界字符了

若没有边界字符的帮忙, 我们很容以作出错误的解读

比方说: 我们用 ab{3,5} 这个 RE (少了 c 这个边界字符)可以抓到 abbbbbbbbbbc (a

10 b )这串字吗

从刚才的 modifier 我们一般会认为我们要的 b 3 5 , 若超出了此范围, 就不是我

们要表达的

因此, 我们或会很轻率的认为这个 RE 抓不到结果... 

然而答案却是可以的! 为甚么呢

让我们重新解读 ab{3,5} 这个 RE 看看

我们要表达的是 a 后接 3 5 b 即可, 3 5 b 后面我们却没规定是甚么

因此在 RE 后面可以是任意的文字, 当然包括 b 也可以啦! (明白了吗?) 

同样的, 我们用 b{3,5}c 也同样可以抓到 abbbbbbbbbbc 这串字的

但我们若使用 ab{3,5}c 这样的 RE , 由于同时有 a c 这两个边界字符, 那就截然不

同了

 

有空再思考一下, 为何我们用下面这些 RE 都可抓到 abc 这串字呢

x* 

ax*, abx*, ax*b 

abcx*, abx*c, ax*bc 

bx*c, bcx*, x*bc 

...(还有更多...) 

, 若我们在这些 RE 前后分别加一个 ^ $ 这样的 anchor, 那又如何呢

 

刚学 RE , 只要能掌握上面这些基本的 meta 大盖就可以入门了

一如前述, RE 是一种规范化的文字表达方式, 主要用于某些文字处理工具之间

grep, perl, vi, awk, sed, 等等. 常用以表示一段连续的字符串, 捕获之或替换之

然而, 每种工具对 RE 表达式的具体解读或有一些细微差异, 不过, 基本原则还是一致的

只要能掌握 RE 的基本原理, 那就一理通百理明了, 只是在实作时稍加变通即可

 

比方以 grep 来说, Linux 上你可找到 grep, egrep, fgrep 这几个程序, 其差异大致如

 

* grep: 

传统的 grep 程序, 在没有参数的情况下, 只输出符合 RE 字符串之句子. 常见参数如下

-v: 逆反模示, 只输出"不含" RE 字符串之句子

-r: 递归模式, 可同时处理所有层级子目录里的文件

-q: 静默模式, 不输出任何结果(stderr 除外. 常用以获取 return value, 符合为 true, 否则

false .) 

-i: 忽略大小写

-w: 整词比对, 类似 \<word\> . 

-n: 同时输出行号

-c: 只输出符合比对的行数

-l: 只输出符合比对的文件名称

-o: 只输出符合 RE 的字符串. (gnu 新版独有, 不见得所有版本都支持.) 

-E: 切换为 egrep . 

 

* egrep: 

grep 的扩充版本, 改良了许多传统 grep 不能或不便的操作. 比方说

- grep 之下不支持 ? + 这两种 modifier, egrep 则可

- grep 不支持 a|b (abc|xyz) 这类"或一"比对, egrep 则可

- grep 在处理 {n,m} , 需用 \{ \} 处理, egrep 则不需

诸如此类的... 我个人会建议能用 egrep 就不用 grep ...  ^_^ 

 

* fgrep: 

不作 RE 处理, 表达式仅作一般字符串处理, 所有 meta 均失去功能

 好了... 

关于 RE 的入门, 我暂时就介绍到这里

虽然写得有点乱, 且有些观念也不很精确, 不过, 姑且算是对大家有一个交差吧.... ^_^ 

若这两天还有时间的话, 我再举些范例来分析一下, 以助大家更好的理解

假如更有可能的话, 也顺道为大家介绍一下 sed 这个工具

(, 这次我不敢作保证了哦... ^_^ )

 

 

 

---------------- 

(顺道一提: eval ) 

 

讲到 command line 的重组特性, 真的需要我们好好的加以理解的

如此便能抽丝剥襺的一层层的将正个 command line 分析得一清二楚, 而不至于含糊

假如这个重组特性理解下来来, 那么, 接下来我们介绍一个好玩的命令 --- eval . 

 

我们在不少变量替换的过程中, 常碰到所谓的复式变量的问题, :  

代码:

a=1 

A1=abc

 

我们都知道 echo $A1 就可得到 abc 这个结果

然而, 我们能否用 $A$a 来取代 $A1 而同样替换出 abc

 

这个问题我们可用很轻松的用 eval 来解决:  

代码:

eval echo \$A$a

 

说穿了, eval 只不过是在命令行完成替换重组后, 再来一次替换重组罢了...