Perl 正则表达式

来源:互联网 发布:java 图片水印 编辑:程序博客网 时间:2024/05/29 03:27
一、正则表达式
1.1 使用简单模式
     $_ = "yabba dabba doo";
     if (/abba/)
     {
             print "matched\n";
     }
     1. 用m//进行匹配:
          a. /abba/是m/abba/的缩写。
          b. 定界符可以是选择:
               成对的: m(abba)、m{abba}、m[abba]、m<abba>
               不成对的:m,abbc,、m!abba!、m^abba^
     2. 列表上下文中的m//:
          如果匹配成功,返回所有捕获变量的列表;否则返回空列表。
          my($first, $second, $third) = /(\S+) (\S+) (\S+)/;
1.2 unicode属性
     每个属性都一个名字;若要匹配某项属性,就要把属性名放入\p{PROPERTY}里面。例如 if(/\p{Space}/) { ... }
     \p{Space}:匹配空白字符。总共有26个不同的字符带有此属性。许多字符属于空白符(whitespace),相当于属性名Space。
     \p{Digit}:匹配数字。  总共有411个不同的数字字符。
     \p{Hex}:匹配十六进制。
1.3 元字符
     1. 在正则表达式中有特殊含义的字符。
          . 是一个字符的通配符,换行符("\n")除外。
          \ 转义字符。
     2. 取消元字符的含义
          在任何元字符前加上反斜线,就会使它失去元字符的特殊作用。
1.4 量词
     * 匹配零次或多次。
     + 匹配一次或多次。
     ? 匹配零次或一次。
     {M, N}
     {M, }
     {, N}
     {M}
1.5 模式分组
     1. 模式分组:
          () 用来分组。
     2. 反向引用:
          /y(....) d\1/ #匹配 "yabba dabba"
          /y(.)(.)\2\1/ #匹配 "yabba"
     3. 嵌套括号,如何区分第几组:
          依次点算左括号的序号就可以了。
          /y((.)(.)\3\2) d\1/ #匹配 "yabba dabba"
     4. 反向引用后面跟数字怎么办?
          /(.)\111/ 
          这是\1、\11、\111?  
          Perl按最长的算,取\111。
     5. \g{N}避免上述歧义:
           /(.)\g{1}11/
          N甚至可以是负数。
     6. \g{label}、\k{label}
          label是命名捕获变量的名字
1.6 择一匹配
     (|) "或",要么匹配左边的内容,要么匹配右边的内容。
1.7 字符集
     一组可能出现的字符。
     [] 匹配其中的任意一个。
     - 表示始末范围。
1.8 字符集的简写
     \d 数字
     /a
     \s 匹配任意空白字符。 匹配5个空白符:换页符(form-feed),水平制表符(tab),换行符(newline),回车符(carriage return),以及空格字符。[\f\t\n\r]
     \h 水平空白符
     \v  垂直空白符(\h\v合起来就是\p{Space})
     \R 匹配断行的那个字符,不管是\r\n还是\n
     \w "单词"字符
1.9 字符集的反义简写
     [^\d]
     [^\w]
     [^\s]
     \D
     \W
     \S
二、用正则表达式进行匹配
2.1 模式匹配修饰符
     /i 进行大小写无关的匹配。
     /s 匹配任意字符(包括换行符),点号(.)不匹配换行符。
     /x 加入空白符(为了好看)。
     组合选项修饰符:
          /is 直接写在一起即可。
2.2 选择一种字符解释方式
     共三种字符解释方式:ASCII、Unicode、locale
     /a 采取ASCII方式
     /u  采取Unicode方式
     /l   遵从本地化语言的设定
2.3 锚位
     \A  字符串的绝对开头
     \z   字符串的绝对末尾
     \Z  行末锚位
    ^  字符串开头
     $  字符串结尾
     /m $和/m表示对多行内容进行匹配。
     \b  单词首尾锚位 /\babba\b/
     \B  非单词边界锚位,它能匹配所有\b不能匹配的位置。
2.4 绑定操作符:=~
     默认操作对象是$_,绑定操作符(=~)拿右边的模式来匹配左边的字符串,而不是匹配$_。
     if ($var =~ /abba/)
2.5 模式中的内插
     正则表达式内部可以进行双引号形式的内插。
     my $what = "test";
     /\A($what)/
2.6 捕获变量
     1. 捕获变量:
          a. 圆括号出现的地方一般都会出发正则表达式引擎捕获匹配到的字符串。
          b. 如果有多个括号,就会捕获多个。
          c. 可以在匹配操作结束后立即通过相应的捕获变量取得这些内容。
          d. 捕获变量名称为:$1、$2、……
          $_ = "yabba dabba doo";
          if (/y(abba)/)
          {
                  print "matched, $1\n";
          }
     2. 捕获变量的存续期:
          a. 存活到下次匹配成功为止;
          b. 失败的匹配不会改动上次成功匹配时获得的内容。
     3. 不捕获模式: ?:
           /y(?:abba)/
     4. 命名捕获: ?<name>
          /y(?<name>abba)/
     5. 自动捕获变量:
          $&、${^PREMATCH}   匹配的字符串前面的内容
          $`、${^MATCH}           匹配的字符串
          $'、${^POSTPATCH}    匹配的字符串后面的内容
2.7 正则表达式优先级
     圆括号(分组或捕获)   (...)、(?:...)、(?<label>...)
     量词                             a*、a+、a?、a{m,n}
     锚位和序列                   abc、^、$、\A、\b、\z、\Z
     择一竖线                      a|b|c
     原子                             a、[abc]、\d、\1、\g{2}
三、用正则表达式处理文本
3.1 用s///进行替换
     1. s///替换:
          s/Name1/Name2/
          s/Name1/Name2/g
          s///返回布尔值,替换成功时为真,否则为假。
     2. 替换字符串,可以使用模式匹配时的捕获变量。
     3. 可用替换修饰符(/g、/i、/x、/s)
          s/Name1/Name2/g
          
3.2 不同的界定符
     成对的:s{https}{http}、s<https>#http#
     不成对的:s#^https#http#;
3.3 模式匹配修饰符
     除了\g,也可以使用普通模式匹配中的/i、/x、/s。
3.4 绑定操作符=~
     默认匹配$_
     $file_name =~ s#^.*/##s #将$file_name中的所有Unix风格的路径全部取出
3.5 无损替换
     1. 先备份,再替换:
          my $copy = $origin;
          $copy =~ s/https/http/;
     2. 备份、替换合在一起:
          (my $copy = $origin) =~ s/https/http/;
     3. 先替换,在备份
           my $copy = $origin =~ s/https/http/r;
          /r会保留原来的值不变,把替换结果作为替换操作的返回值返回。
3.6 大小写转换
     \U 将其后的字符全部转为大写
     \L 将其后的字符全部转为小写
     \u 将其后的第一个字符转为大写
     \l  将其后的第一个字符转为小写
     \E 关闭大小写转换的功能
3.7 split函数、join函数
     1. split函数
          my @fields = split /:/,"a:b:c";    #得到("a", "b", "c")
          默认split以空白符分隔$_。
     2. join函数
          my @result = jooin ":", a, b, c;    #得到“a:b:c”
          至少两个元素,否则合并后为空。
四、更强大的正则表达式
4.1 非贪婪量词
     非贪婪量词:尽可能少的匹配。之前都是尽量匹配长字符串。
     *?         匹配零次或多次。
     +?        匹配一次或多次。
     ??       匹配零次或一次。
     {M, N}?
4.2 跨行的模式匹配
     $_ = "I'm much better\nthan Barnet is\nat bowling, \nWilma.\n"
     ^和$是整个字符串的开头和结尾。
     /m,加上/m修饰符后,就可以匹配字符串的每一行。
4.3 一次更新多个文件
     $^I = ".bak";
     while (<>)
     {
             s///g;
     }
     1. <>自动打开许多文件,如果没有指定文件,它会从标准输入读进数据。
     2. $^I是个字符串,会变成备份文件的扩展名。
     3. 该命令修改了原始文件的内容file.dat,原始文件内容备份到了file.dat.bak。
4.4 从命令行直接编辑
     perl -p -i.bak -w -e 's///g' file*.dat
     功能同上一节。
     -p
          让Perl自动生成一段小程序,类似如下:
          while(<>)
          {
               print;
          }
     -i.bak
          把$^I设置为".bak"。
     -e
          后面就是可供执行的程序代码。
     file*.dat
          匹配的所有文件

0 0