文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Regualar Expresstion

Regualar Expresstion

时间:2006-03-17  来源:科罗拉多

规则表示式的运用

 

在本系列文章一开始就说明了学 vi(m) 可以顺便学规则表示式(regular expression,以下简称 regexp),那为什么到现在才来讲呢?因为 regexp 说简单也算不很难,但您要深入去使用的话,有时会马上看不出一个复杂的 regexp 在说些什么的,就曾有人形容 regexp 为「有字天书」!而且在 vi(m) 整体都还没一个概念就加入 regexp 的话,那后面的单元恐怕就没人看了!而 regexp 各家有各家的 extensions,这也是大家视为畏途的原因之一,不过总是大同小异,只需注意一下就可以了。目前先不必管别家怎么说,就让 vim 暂时先成为我们的「标准」,以后碰到其它程序的 regexp 应该就可以触类旁通。以下我们尽量由实例去了解。当然,小小的一篇文章是没有办法详尽介绍,只能捡重点来说明了。如有疑问,可 :h pattern 或在 Un*x 系统中可 man 7 regex,甚至 man ed,man sed,man grep,man awk,man perlre 里面也是会说些 regexp,但要注意和 vim 差异的地方!其中 perl 的 regexp 应该是最完整的了,如果您的系统没有 perl 那应该是「稀有动物」了!:-) ㄟㄟㄟ!vim 只是一个编辑器,可不是独立的程序语言!

 

基本的匹配

 
*  指前所绑住的字符或字符集合,出现 0 次或 0 次以上。
\+  * 作用相同,但不包括出现 0 次。
\= 指前所绑住的字符恰好出现 0  1 次。
\| 这是多选,就是 or 的意思,被 \| 隔开的 pattern,任一个符
   合的话就算符合。
  • \+, \=, \| 会加上一个 \,是因原字符在 vi(m) 就具有特殊意义,在一般的 regexp 中是 +,?,| 就可以了,只是提醒您一下,以免搞混了!
  • 记住 * \+ 是不可数的!用辞不是是精确,只是帮助您记忆啦!
  • 在 elvis 及 ed 中是使用 \? 来匹配出现 0 或 1 次,而不是 \=,这里要非常小心!

[实例] dg*
指 * 前所绑住的字符 g 出现 0 次或 0 次以上。也就是说 d(出现 0 次),dg,dgggg,dgggggggg 都是符合这个 pattern。如果您下寻找指令 /dg*,那符合这个 pattern 的字符串都会被找出来。如果用在代换就要非常小心了,像 extended 中的 d 也是会被置换掉的。例如您下 :%s/dg*/test/g 的话,那 extended 这个字会换成 extentestetest。

  • shell 中使用的通用字符为 pattern matching notation 和 regexp 不同的。dg* 在 shell 中是解为以 dg 开头的任意字符串,这就不包括 d 在内了,也就是说在 shell 中,* 是代表任一字符或字符串。

[实例] dg\+
dg, dgg, dgggggg 皆符合,但 d 则不符合。如果是 dg\= 的话,就只有 d、dg 这两个符合了。

 

[实例] :%s/The\|All/test/g
全文中只要是 The 或 All 都会被替换成 test。注意,如果文中有 There 也是会被替换成 testre!要如何避免这种情形呢?下面会另述及限定使用法。

 

[实例] /123-\=4567
这样会找出,123-4567 及 1234567。当然 123-456789 也是会被找出来。

 
[...]  字符集合,表示中括号中所有字符中的其中一个。
[^..]  这是上述 [...] 的补集,表非中括号内字符的其中一个。
.      除换行字符外的任一单一字符。指本身,非指前所绑之字符。
       就好像 shell 中的 ? 一样。如果要指定真正的英文句点,要
        \  escape,就是说 \. 这时的 . 是代表真正句点,而不
        regexp 中的特殊意义。其它如 \* 亦同。

[实例]

[Aa]

A 或 a 其中的一个。

[12345]

12345 其中的一个数目字。可用 [1-5] 来表示。连续性的数目字或字符可用 - 来隔开,写出头尾来代表就可以了。[0-9] 就表 0 到 9 的数目字,[a-d] 就代表 abcd 四个英文字母

 

[实例] W[0-9]*\.cc
这个例子是说以 W 开头,后接 0-9 其中一个或多个数目字或不接什么,然后是一个句点,最后是 cc。所以 W.cc,W1.cc,W2.cc,W345.cc,W8976543287.cc 皆符合。如果要表示 W 及 .cc 间夹一个以上的数目字,要写成 W[0-9][0-9]*\.cc。

 

[实例] .*
这代表任意字符或字符串,或什么都没有,脑筋急转弯,对照前面的定义想一下。当然这是不包括换行字符的。

 

[实例]
[^M] 表除 M 以外的任意字符。
[^Tt] 表 T 及 t 以外的任意字符。
[^0-9] 表非数目字之字符。
[^a-zA-Z] 表非英文字母之字符。

  • 注意,^ 要在中括号内,且在最开头的地方,否则另有含意。
 
^  匹配行首,指其后绑住的字符串,出现在行首才符合。
$  匹配行尾,指其前绑住的字符串,出现在行尾才符合。含换行字符。
  • 不是在行首的 ^ 指的是 ^ 这个字符。不是在行尾的 $ 是指 $ 本身这个字符。

[实例] /^What
这样只有在行首的 What 才会被找出来。注意! Whatever, What's 也是会被找出来。如果是 /What$ 则是在行尾的 What 才会被找出来。

 

[实例] ^$
这是什么东东?行首也是行尾的行。ㄚ,就是空白行嘛!当然也不能说这个行是没有什么东东啦!空白行至少也是会有个换行字符。在后面会详述如何消除全文的空白行。

 
\(...\)  记忆 pattern,可由 \1, \2...\9 来叫出。

[实例] :%s/\([a-z]\)\1/test/g
这样 aa, bb, cc, dd, ..., zz 都会被 test 替换掉。这和 :%s/[a-z][a-z]/test/g 是不一样的意思,后者会把 aa, ab, ac... ba, bb, bc...zz 都换成 test。也就是说 \(...\) 由 \1 叫出时会有对称性的配对出现。

 

[实例] :%s/\(.\)\(.\)r\2\1/test/g
会将中间为 r,前有二个任一字符,后有两个具对称性的字符所组成的字符串替换成 test。\2 是呼叫第二组 \(.\),而 \1 是呼叫第一组 \(.\)。例如:12r21,cfrfc,7grg7 等都会被替换成 test。

 
\<  匹配字(word)首。所谓 word 包括文数字及底线。
\>  匹配字尾。这就是前所提及的限定用法,被 \<,或 \> 括住的
    pattern 就会被限制住,使 regexp 不能再向右(左)扩充解释。
  • ed 及 perl 中可以 \b 来表示这两个符号,perl 中只支持 \b,ed 则 \b 及 \<, \>皆支援。但在 perl 可多加个 ? 来限制 regexp 的扩充解译。
  • 功能上而言,这是和 ^ $ 一样的定位样式(anchor pattern)指所绑住的字符串必须是单字边界(word boundary),前或后或前后除了空格符及标点符号外不可再有其它字符。
  • 在 vim 中 \b 是表示 <BS> 即 backspace 键。

[实例] :%s/\<abbbc\>/test/g
这样只有 abbbc 才会被替换成 test。如果没有这样限定,:%s/abbbc/test/g,那 deabbbcly 中的 "abbbc" 亦会被替换成 test。所以前面 :%s/The\|All/test/g 可换成 :%s/\<The\>\|\<All\>/test/g 这样一来,There 就不会被替换成 testre 了!

 

[实例] :%s/\<abbbc/test/g
这样的话,只要是以 abbbc 为首的字(word),其中的 abbbc 的部份都会被 test 所替换。注意!是指前缀,而不是指行首。所以 abbbc,abbbcerd,abbbckijuds 都符合。

 
\{n,m}  指前所绑住的字符或字符集合最少出现 n 次,最多出现 m 次。
  • 这在一般的 regexp 表示成 \{n,m\}。vim 及 elvis 两种表示法皆支持。perl 则直接使用 {}。以下会举四种不同的例子,请大家发挥一下想象力。:-)

[实例] \{最小值,最大值}
如 [0-9]\{3,4} 匹配至少三位数,但不可多于四位数的数目字。如:

 
  123
  12
  1
  123456
  1234567
  12345678
  1234
  12345

如果下 :%s/[0-9]\{3,4}/test/g 的话,那 1,12 这两组不会被替换,因为不满 3 位数。而 12345,则会换成 test5。123456,则会换成 test56。12345678,则会换成 testtest。1234567 也是会换成 testtest。123,1234 这两组则会被替换成 test。您可以亲自操作一次就知道怎么一回事了。操作时最后加 gc 来 confirm,这样您会更了解实际替换的内容。ㄟ,别忘了 u 可以回复您的编辑动作。

 

[实例] \{数目字}
xy\{20} 表示 x 后接 20 个 y。
e[x-z]\{4} 表示 e 后接有四个字符,是 x,y,z 的其中一个的
      组合。如:exxxx, exyyz, ezzyz, exyzz 皆符合。

 

[实例] \{最小值,}
xy\{2,} 表 x 后接至少二个的 y。相当于 xyyy* 或 xyy\+ 。

 

[实例] \{,最大值}
xy\{,4} 表 x 后接至多四个或更少的 y (可能没有)。
     因此 x, xy, xyy ,xyyy, xyyyy 皆符合。

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载