Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1738909
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: Python/Ruby

2012-03-26 11:13:25

可以用操作符“=~”和“=!”来进行模式匹配:


  1. $string = 'abcdef';
  2. print $string =~ "bcd" . "\n"; # 1 即true
  3. print $string =! "bcd" . "\n"; # null 即false

上面的例子中=~表示$string包含了bcd,=!表示$string不包含bcd。

模式匹配的标准形式是用斜杠来表示的:


  1. $string =~ m/bcd/

最前面的m表示匹配(match)。两斜杠中间的字符串是用来匹配的内容。在最后的斜杠的右侧可以加入匹配选项,比如g表示匹配多个:
  1. @matches = 'abcdefbcdgh' =~ m/bcd/g

利用g选项,可以让匹配返回一个数组。上例的@matches有两项,值都为"bcd"。前面的m可以省略,而最后的选项也是可选的,所以最简单的匹配方式就是:
  1. $string =~ /bcd/;


匹配的内容可以是正则表达式:
  1. sub printMatches {
  2.     foreach $s (@_)
  3.     {
  4.         print "||" . $s . "|| ";
  5.     }
  6.     print "\n";
  7. }

  8. # 字符+表示前面的字符出现一次或多次
  9. printMatches 'babaaba' =~ /a+b/g; # ||ab|| ||aab||

  10. # 字符*表示前面的字符出现零次、一次或多次
  11. printMatches 'babaaba' =~ /a*b/g; # ||b|| ||ab|| ||aab||

  12. # 字符?表示前面的字符出现零次或一次
  13. printMatches 'babaaba' =~ /a?b/g; # ||b|| ||ab|| ||ab||

  14. # 利用反斜杠表示转义
  15. printMatches '*+?' =~ /\*\+\?/g; # ||*+?||

  16. # 字符[]表示一组字符中的某一个
  17. printMatches 'abacadae' =~ /a[cd]/g; # ||ac|| ||ad||

  18. # 字符[^]表示不匹配一组字符中的任一个
  19. printMatches 'abacadae' =~ /a[^cd]/g; # ||ab|| ||ae||

  20. # 匹配字母或数字
  21. printMatches 'šiC79@' =~ /[a-z|A-Z][0-9]/g; # ||x9|| ||C7||

  22. # 字符^或\A匹配串首
  23. printMatches 'abc9abd' =~ /^ab[a-z]/g; # ||abc||

  24. # 字符$或\Z匹配串尾
  25. printMatches 'abc9abd' =~ /ab[a-z]$/g; # ||abd||

  26. # 字符\b表示单词边界
  27. printMatches 'aw1 w2 w3a' =~ /\bw[1-9]/g; # ||w2|| ||w3||
  28. printMatches 'aw1 w2 w3a' =~ /w[1-9]\b/g; # ||w1|| ||w2||

  29. # 字符\B表示单词内部,即非单词边界
  30. printMatches 'aw1 w2 w3a' =~ /\Bw[1-9]/g; # ||w1||
  31. printMatches 'aw1 w2 w3a' =~ /w[1-9]\B/g; # ||w3||

  32. # \d表示任意数字
  33. printMatches 'w@aw1wgw3' =~ /w\d/g; # ||w1|| ||w3||

  34. # \D表示非数字
  35. printMatches 'w@aw1wgw3' =~ /w\D/g; # ||w@|| ||wg||

  36. # \w表示任意单词字符,即字母与数字
  37. printMatches '#ab#d@#89#!' =~ /#\w+/g; # ||#ab|| ||#d|| ||#89||

  38. # \W表示非单词字符
  39. printMatches '#ab#d@#89#!' =~ /#\W+/g; # ||#!||

  40. # \s表示空白字符
  41. printMatches 'a bc def ghij' =~ /\w+\s/g; # ||a || ||bc || ||def ||

  42. # \S表示非空白字符
  43. printMatches 'a bc def ghij' =~ /\w+\S/g; # ||bc|| ||def|| ||ghij||

  44. # .表示除换行外的任意字符
  45. printMatches 'a@a2ab' =~ /a./g; # ||a@|| ||a2|| ||ab||

  46. # {}用于指定匹配字符出现的次数
  47. printMatches 'ababbabbbabbbb' =~ /ab{2,3}/g; # ||abb|| ||abbb|| ||abbb||
  48. printMatches 'ababbabbbabbbb' =~ /ab{1}[^b]/g; # ||aba||
  49. printMatches 'ababbabbbabbbb' =~ /ab{3,}/g; # ||abbb|| ||abbbb||

  50. # |用来匹配多种模式
  51. printMatches 'isa82@32&64' =~ /[a-z]+\d+|@\d+/g; # ||isa82|| ||@32||


特殊字符也有优先级(由上至下优先级由高到低):

特殊字符 描述
() 模式内存
+ * ? {} 出现次数
^ $ \b \B
| 选项

 


  1. # 可以用任意字符来作为模式定界符来代替默认的/
  2. printMatches 'ab///c/d' =~ m#[a-z]/+#g; # ||b///|| ||c/||


圆括号可以把部分组合成整体:
  1. # 用()可以将不同的部分组合起来,作为整体进行重复匹配
  2. printMatches 'ab#abab#ababab#aba' =~ /(ab){3}/g; # ||ab|| (返回的值为圆括号最后一次匹配的字符串)
  3. print $&; # ababab ($&用来存储最后一次匹配的结果)
  4. printMatches 'aabbabab' =~ /(ab){3}/g; # null

  5. # $1,$2,...用来存放各个组(即圆括号)最后一次匹配的结果
  6. printMatches 'a1=b2#c3-d4 e5=f6#g7-h8' =~ /(\w+)=(\w+)#(\w+)-(\w+)/g; # ||a1|| ||b2|| ||c3|| ||d4|| ||e5|| ||f6|| ||g7|| ||h8||
  7. print "$1, $2, $3, $4, $5, $6, $7, $8\n"; # e5, f6, g7, h8, , , , (字符串中有两个匹配,最后一次匹配到的串是e5=f6#g7-h8,所以$1其实是最后匹配到的串中的第一个组)

 

最后斜杠后面的模式选项:


  1. # g选项匹配所有可能的模式
  2. @matches = "aa.bb.cc" =~ /\w+/g; # aa, bb, cc
  3. print "@matches\n";

  4. while ("ab,abab,ababab" =~ /(ab)+/g)
  5. {
  6.     print "$&\n";
  7. }

  8. # g选项下可以用pos来返回或设置字符串的匹配位置
  9. $string = "a1a2a3a4";
  10. $index = pos($string); # null
  11. $string =~ /a\d/g; # a1
  12. $index = pos $string; # 2 匹配了a1这两个字符
  13. $string =~ /a\d/g; # a2
  14. pos($string) = 6;
  15. $string =~ /a\d/g; # a4 略过了中间的a3

  16. # i选项忽略大小写
  17. printMatches 'A2a3' =~ /a\d/g; # ||a3||
  18. printMatches 'A2a3' =~ /a\d/ig; # ||A2|| ||a3||

  19. # m选项将字符串看作多行
  20. printMatches "first line\nseconde line" =~ /.*line$/g; # ||seconde line||
  21. printMatches "first line\nseconde line" =~ /.*line$/gm; # ||first line|| ||seconde line||

  22. # s选项把字符串看作单行,使得.可以匹配\n。
  23. printMatches "first line\nsecond line" =~ /.*line$/g; # ||seconde line||
  24. printMatches "first line\nsecond line" =~ /.*line$/gs; # ||first line(换行)second line||

  25. # o选项只赋值一次
  26. $var = "a";
  27. for ($i = 1; $i <= 3; $i++)
  28. {
  29.     printMatches "ab" =~ /$var/go; # a, a, a
  30.     $var = "b";
  31. }

  32. $var = "a";
  33. for ($i = 1; $i <= 3; $i++)
  34. {
  35.     printMatches "ab" =~ /$var/g; # a, b, b
  36.     $var = "b";
  37. }

  38. # x忽略模式中的空白
  39. printMatches "a b c def" =~ /\w \w \w/g; # ||a b c||
  40. printMatches "a b c def" =~ /\w \w \w/gx; # ||def||


替换操作符:和匹配的形式类似,语法为s/pattern/replacement/:
  1. $string = '@#a&^b09-+cd=[';
  2. $num = $string =~ s/\W/\*/g; # $num = 8(替换了8处),$string = **a**b09**cd**

替换操作符的模式选项和匹配的模式选项基本一样(g,i,m,s,o,x,),但多一个选项e,表示把替换部分看作表达式:
  1. $string = 'a1a2a3';
  2. $string =~ s/\d/{1}*2/ge; # a2a4a6
  3. $string =~ s/\d/{1}*2/g; # a2*2a4*2a6*2


翻译操作符:语法为tr/string1/string2/,将string1里的字符一一替换为string2中相应位置的字符:
  1. $string = "abcdegcba";
  2. $string =~ tr/abc/xyz/; # xyzdegzyx 相应的字符会替换为第二个字符串中相应的字符

  3. $string = "abcdegcba";
  4. $string =~ tr/abc/xy/; # xyydegyyx 多出来的c,替换为最末尾的y

  5. $string = "abcdegcba";
  6. $string =~ tr/abc/xyzw/; # xyzdegzyx 最后一个w被忽略

  7. $string = "abcdegcba";
  8. $string =~ tr/aba/xyz/; # xycdegcyx 第一个a被替换,第二个a被忽略

  9. $string = "aabc+degcba";
  10. $string =~ tr/a+/xy/; # xxbcydegcbx 翻译操作符不支持正则表达式,+号被替换为y

翻译操作符支持三种模式选项:


  1. # c选项翻译所有未指定的字符
  2. $string = "a32()64aca";
  3. $string =~ tr/0-9/*/c; # *32**64***

  4. # d选项删除所有指定字符
  5. $string = "a32()64aca";
  6. $string =~ tr/0-9/*/d; # a()aca

  7. # s选项把非指定的字符缩成一个字符
  8. $string = "a32()64aca";
  9. $string =~ tr/0-9/*/s; # a*()*aca


扩展模式匹配的语法为(?pattern),其中c为一个字符。它有以下用法:
表示不存贮圆括号的内容:
  1. # ?:表示不存贮括号内的匹配内容
  2. printMatches "abcdef" =~ /(abc)(def)/; # ||abc|| ||def||


  3. 表示内嵌模式选项,可以是i,m,s,x:

  4. # 内嵌模式选项i
  5. printMatches "aA bB" =~ /(?i)aa|bb/g; # ||aA|| ||bB||
  6. printMatches "aA bB" =~ /aa|(?i)bb/g; # ||bB||
  7. printMatches "aA bB" =~ /aa|bb/gi; # ||aA|| ||bB||

  8. # 内嵌模式选项m
  9. printMatches "line1\nline2\n" =~ /(?m)line\d$/g; # ||line1|| ||line2||

  10. # 内嵌模式选项s
  11. printMatches "line1\nline2\n" =~ /(?s).*line\d$/g; # ||line1 换行 line2||

  12. # 内嵌模式选项x
  13. printMatches "abc,def" =~ /(?x)a b c/g; # ||abc||


表示预见匹配:
  1. # 肯定预见匹配
  2. printMatches "1a2b3c" =~ /\d(?=b)/g; # ||2|| 下一位的b只被预览,而没有被匹配

  3. # 否定预见匹配
  4. printMatches "1a2b3c" =~ /\d(?!b)/g; # ||1|| ||3||


表注释:
  1. # ?#表注释
  2. printMatches "hello" =~ /he(?#注释)/g; # ||he||

阅读(1124) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~