您的位置:首页 > 其它

perl之正则表达式

2015-12-28 20:33 323 查看
特殊字符:

^ :(读:hat) 匹配一行的开始。例如正则表达式“^regex”能够匹配字符串“regex我会用”的开始,但是不能匹配“我会用regex”。

$ :类似^,匹配结尾。

| 表示 或  z|food 表示 z 或者 food 并非zood或food

[] 匹配括号中的任何一个字符

. (点)匹配除\n之外的任何单个字符。

*:限定符,匹配0至多个在它之前的子表达式,和通配符*没关系。

+:限定符,类似* ,但必须出现一次。

? : 类似*,但是值是0次或1次。

{} :限定符号,表示前面的字符必须出现括号内填的次数。如[0-9]{6} 表示0-9中的任意数字必须出现6次。

{,}:如[0-9]{6,}表示至少出现6次,最多无限次。[0-9]{6,10}表示至少6次,最多10次。

\d:代表一个数字,等同于[0-9] ; # \\d  →\d

\D:代表非数字,等同于[^0-9]

\s:代表换行符、Tab制表符等空白字符 ,(空格、回车、制表符)

\S:代表非空白字符(a0%$@@)

\w:匹配字母或数字或下划线或汉字,即能组成单词的字符,除%&#@!$等字符。[a-zA-Z0-9_汉字]

\W:非\w ,等同于[^\w] %

正则表达式:http://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F

【Perl】perl正则表达式中的元字符、转义字符、量词及匹配方式:http://blog.sina.com.cn/s/blog_6a6c136d0101aqra.html

匹配模式:

模式匹配

语法为:(m)/pattern/option

$result =( $expression =~ /pattern/);       #匹配的结果$result,为true或false。若在该字符串中找到了该模式,则返回非零值,即true,不匹配则返回0,

或$_=$expression;  $result = /pattern/;    #默认匹配$_

1)标量$result替换为数组@arrRet 时:@arrRet =( $expression =~ /pattern/);用数组存储匹配上的内容。

2)匹配选项,语法为:/(?option)pattern/,等价于/pattern/option。

     描述: g 匹配所有可能的模式; i 忽略大小写; m 将串视为多行; o 只赋值一次; s 将串视为单
4000
行; x 忽略模式中的空白;

3)*、+均为贪婪匹配;对应的最小匹配:*?、+?。

4)模式中如果出现 () ,则发生匹配或替换后, () 内的模式被 Perl 解释器自动依次赋给系统 $1, $2 ......($num或\num)

替换操作符

   语法为s/pattern/replacement/,其效果为将字符串中与pattern匹配的部分换成replacement。如:

     $string = "abc123def";

     $string =~ s/123/456/; # now $string = "abc456def";

 1) 在替换部分可使用模式次序变量$n,如s/(\d+)/[$1]/,但在替换部分不支持模式的特殊字符,

          如{},*,+等,如s/abc/[def]/将把abc替换为[def];

2)  选项描述:g 匹配所有可能的模式; i 忽略大小写; m 将串视为多行; o 只赋值一次; s 将串视为单行; x 忽略模式中的空白;

3)替换与匹配的区别:

      A)匹配结果返回的是数组,元素为匹配到的“()”模式,即$1、$2...

      B)  被替换的是整个正则表达式,而不是所谓的$1、$2...

翻译操作符

这是另一种替换方式,语法如:tr/string1/string2/。同样,string2为替换部分,但其效果是把string1中的第一个字符替换为string2中的第一个字符,把string1中的第二个字符替换为string2中的第二个字符,依此类推。如:

     $string = "abcdefghicba";

     $string =~ tr/abc/def/; # now string = "defdefghifed"

   当string1比string2长时,其多余字符替换为string2的最后一个字符;当string1中同一个字符出现多次时,将使用第一个替换字符。

选项描述: c 翻译所有未指定字符; d 删除所有指定字符; s 把多个相同的输出字符缩成一个

高级表达

捕获组与非捕获组: http://www.cnblogs.com/wuhong/archive/2011/02/18/1957017.html

正则表达式-分组:http://blog.csdn.net/longyulu/article/details/8965684

                             http://www.360doc.com/content/10/1104/20/2224885_66653049.shtml

模式匹配 [b]扩展[/b]

1、捕获组

1)捕获组:/(pattern) / , 匹配pattern(且匹配结果包含pattern),并捕获匹配结果,自动设置组号。如:

 / (abc)+d/ , 匹配abcd或者abcabcd

2) 对捕获组的反向引用:\num,其中 num 是一个正整数。如:

(\w)(\w)\2\1,匹配abba

2、非捕获组

  以 (?) 开头的组是纯的非捕获 组,它不捕获文本 ,也不针对组合计进行计数。

1)(?:uncap_pattern) :匹配uncap_pattern;

    (且匹配结果包含uncap_pattern,匹配指针要偏移),但不捕获匹配结果。如:

     / 'industr(?:y|ies)/ 匹配'industry'或'industries'。

2)零宽度正向和负向的预查 lookahead:匹配后面跟的是uncap_pattern的位置pattern;

  (但匹配结果不包含uncap_pattern,匹配指针不要偏移),但不捕获匹配结果。

    正向的预查 ,语法为:

    /pattern(?=uncap_pattern)/ ; #其意义为匹配后面为uncap_pattern的pattern模式; 如:

     $string = "25abc8";

     $string =~ /abc(?=[0-9])/; 

     $matched = $&;       # $&为已匹配的模式,此处为abc,而不是abc8

    相反的,负向的预查:

    (?!uncap_pattern),意义为匹配后面非uncap_pattern的pattern模式。     

3)零宽度正向和负向的回查 lookbehind:匹配前面是uncap_pattern的位置pattern;

    (但匹配结果不包含uncap_pattern,匹配指针不要偏移),但不捕获匹配结果。

     正向回查,语法:(?<=uncap_pattern)pattern。 #其意义为匹配前面是uncap_pattern的位置pattern;   如:

     / (?<=Office|Word|Excel)2000/   #匹配 " Office2000" 中的 "2000",不匹配 "Windows2000" 中的 "2000"。

    负向回查:pattern(?<!uncap_pattern)

3、模式注释

   PERL5中可以在模式中用?#来加注释,如:

     if ($string =~ /(?i)[a-z]{2,3}(?# match two or three alphabetic characters)/ {

       ...

     }

举例:####扩展模式匹配:肯定的和否定的预见匹配(向前查找、向后查找)

my $digits="123456789";

my @nonlap=$digits=~/(\d\d\d)/g;  #123 456 789.表示每次匹配的是三个连续数字,匹配成功后匹配指针+3

my @yeslap=$digits=~/(?=(\d\d\d))/g;   #123 234 345 456 567 678 789.整体匹配的不是三个连续数字,而是它前面的表达式,意思是后面是三个连续数字的字符,这里是空字符,成功后匹配指针+1;但返回给数组的是第一个有效的捕获组(即是(\d\d\d))。

print  "Non-overlapping:@nonlap\n";

print  "overlapping:@yeslap\n";

@yeslap=$digits=~/\d(?=\d\d\d)/g; #1 2 3 4 5 6.

print  "overlapping:@yeslap\n";

@yeslap=$digits=~/\d(?:\d\d\d)/g; #1234 5678

print  "overlapping:@yeslap\n";

@yeslap=$digits=~/\d(?=(\d\d\d))/g; #234 345 456 567 678 789

print  "overlapping:@yeslap\n";

关于正则表达式的逻辑与或非:

1.正则表达式的逻辑与、或、非,

1)逻辑或:

  pattern1|pattern2, 模式pattern1或pattern2均可匹配,如: p0 (?: p1|p2)p3;

2)逻辑非:

  A) 单字符的非:[^abcd], 匹配非abcd中的任一字符

B) 模式的非:对应着非捕获组中的负向预查(?!pattern)或负向回查(?<!pattern),即可实现逻辑非。

  当然,通过多个正则表达式也可实现逻辑非,如:

  对逻辑非,可以用两个正则表达式实现,这里有个小技巧,比如字符串C,匹配^AB(即所有前面不是A的B),通过三部实现:

  a)可以先将AB替换为特殊字符串F: C =~ s/AB/F/g;

  b)匹配或替换B字符串:C = ~ s /B//g;

  c)将字符串F替换回AB:C =~ s/F/AB/g;

3)逻辑与:

正则表达式是对有序字符串的匹配,强调字符间的顺序。所以想表达,“同时匹配模式A和B”,需用:(A.*B)|(B.*A)。

perl正则应用的一些小技巧:

1、UltraEdit支持perl正则查找和替换,工作中很方便使用。注意:

1)UE默认是按单行查找的,即任意字符"."不包括换行符。

2)匹配多行(查找段落),需用到换行符:“\r\n"

3)  A) 尽量避免捕获组,而多使用非捕获(?:P)、(?=P)、(?<=P)或(?!P)、(?<!P),以减少正则匹配的内存开销和效率;

     B) 正向的回查和预查只应出现在正则表达式的最左边和最右边: 只能是(?<=P0)P1(?=P2);

          禁止出现"(?=P0)P1"、"P1(?<=P0)",为非法的,无法匹配到任何结果;

     C)负向的预查(?!P0)和负向的回查(?<!P0),可以出现在正则的任何位置,如:

         mytest(?!case).*   #除去mytestcase的test.*

         .*(?<!mytest)case   #除去mytestcase的.*test

     D)回查(?<=P0)、(?<!P0)中的正则P0,必须是固定长,不能为变长;但 预查中的正则,可以是变长。如:

         (?<!abc)135 #合法;(?<!abc*)135 #非法;  (?<=abc*)135 #非法; 

          (?!abc*)135 #合法  135(?=abc*) #合法

        若要实现变长的类似正向回查的功能,可使用元字符:'\K' : (大写K)使\K左侧部分,不引入到$&中。        

4) 不包含模式A的任意字符:".(?!A) "  ;   如查找不包含模式A的行:"^(?!A)(.(?!A))*\r\n"

#例子:去除casehead头(以/********开始,以********/结束的段落)中所有的引号" :

       (/\*{8}(?:(?:.(?!\*/))*?\r\n)*?.*)"(.*(?:(?:.(?!\*/))*?\r\n)*?.*\*{8}/) 替换为 $1$2

     或

      (/\*{8}(?:(?:.(?!\*/))*?\r\n)*?.*)\K"(?=.*(?:(?:.(?!\*/))*?\r\n)*?.*\*{8}/) 替换为空 ""         #元字符\K:替代变长的回查

2、对除去某些“特定段”的匹配或替换的处理。 比如,要去除某行中的ABC,但是两个"之间的不被处理。这样,匹配或替换就需要在除去这些"段"的基础上进行。普遍的做法可以是:(如 my $str = qq  ABCDEFG "ABCD" ABCD;)

    1)先预处理:保存所有”特定的段“到数组;

      my  @arrPam = ($str =~ m{".*?"}{}g);  #特定“段”:两个"之间;

    2 )将”特定的段“替换为唯一的标识;

      my $special = "!F@D4#Ls$3m%rt4^b_94754&y#c*q";

      my  $str =~ s{".*?"}{$special}g); #替换特定"段"

    3) 对预处理后的字符串进行匹配或替换操作。

       $str =~ s{ABC}{}g); 

    4) 恢复所有特定"段";

        for (my $i=0;$i < $#arrPam ;$i++ )

        {

               $str =~ s{$special}{arrPam[$i]}; #替换为所保留的"段"。注意:不带选项g。    

        }

      不知道是否有一个正则可以搞定的,现在是还没找到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  脚本 perl 正则