powerful Regular Expression!   

powerful Regular Expression!

强大的正则表达式

25 Aug 2016

Go back powerful Regular Expression

数理一下强大的perl正则表达式

正则表达式是 Perl 语言的一大特色,也是 Perl 程序中的一点难点,不过如果大家能够很好的掌握他,就可以轻易地用正则表达式来完成字符串处理的任务,当然在 CGI 程序设计中就更能得心应手了。下面我们列出一些正则表达式书写时的一些基本语法规则。

1. 正则表达式的三种形式

1.1 理论:

首先我们应该知道 Perl 程序中,正则表达式有三种存在形式,他们分别是:

  • 匹配:m/<regexp>/ (还可以简写为 /<regexp>/ ,略去 m)

常用的后缀修饰: /i不区分大小写 /s匹配任何字符

  • 替换:s/<pattern>/<replacement>/

常用的后缀修饰: /g进行全局替换

  • 转化:tr/<pattern>/<replacemnt>/

这三种形式一般都和 =~ 或 !~ 搭配使用,“=~” 表示相匹配(does),“!~” 表示不匹配(doesn’t),并在左侧有待处理的标量变量.如果没有该要处理的变量,则默认为处理 $_ 变量中的内容.

1.2 实例:

$str = "I love Perl";

$str =~ m/Perl/; 
# 表示如果在 $str 中发现 "Perl" 字符串,则返回 "1" 否则返回 "0"。
print($str =~ m/Perl/);
print "\n";
#等同于
$result=$str =~ m/Perl/;
print $result."\n";

$str =~ s/Perl/BASH/; 
# 表示将变量 $str 中的 "Perl" 字符串替换为 "BASH",如果发生此替换则返回 "1",否则返回 "0"。
print "$str\n";
$str =~ tr/A-Z/a-z/; 
# 表示将变量 $str 中的所有大写字母转化为小写字母,如果转化发生了则返回 "0",否则返回 "1"。
print "$str\n";
## 1
## 1
## I love BASH
## i love bash

捕获:

Perl 的正则表达式中如果出现 () ,则发生匹配或替换后 () 内的模式被 Perl 解释器自动依次赋给系统 $1, $2 …… 请看下面的例子:

$string = "I love perl";

$string =~ s/(love)/<$1>/; 
# 此时 $1 = "love",并且该替换的结果是将 $string 变为 "I <love>; perl"
print "$1\t$string\n";

$string = "i love perl";

$string =~ s/(i)(.*)(perl)/<$3>;$2<$1>;/; 
# 这里 $1 = "i",$2 = " love ",$3 = "perl",并且替换后 $string 变为 "<perl>; love <i>;"
print "$1\t$2\t$3\n$string\n";
## love I <love> perl
## i     love   perl
## <perl>; love <i>;

2.表达式中的一些常用模式.

2.1 表达式

表达式 结果 表达式 结果
. 匹配除换行符以外的所有字符 x? 匹配 0 次或一次 x 字符串
x* 匹配 0 次或多次 x 字符串,但匹配可能的最少次数 x+ 匹配 1 次或多次 x 字符串,但匹配可能的最少次数
.* 匹配 0 次或多次的任何字符 .+ 匹配 1 次或多次的任何字符
{m} 匹配刚好是 m 个 的指定字符串 {m,n} 匹配在 m个 以上 n个 以下 的指定字符串
{m,} 匹配 m个 以上 的指定字符串 [] 匹配符合 [] 内的字符
[^] 匹配不符合 [] 内的字符 [0-9] 匹配所有数字字符
[a-z] 匹配所有小写字母字符 [^0-9] 匹配所有非数字字符
[^a-z] 匹配所有非小写字母字符 ^ 匹配字符开头的字符
$ 匹配字符结尾的字符 匹配一个数字的字符,和 [0-9] 语法一样
\d+ 匹配多个数字字符串,和 [0-9]+ 语法一样 非数字,其他同 \d
\D+ 非数字,其他同 \d+ \w 英文字母或数字的字符串,和 [a-zA-Z0-9] 语法一样
\w+ 和 [a-zA-Z0-9]+ 语法一样 \s 空格,和 [\n\t\r\f] 语法一样
\s+ 和 [\n\t\r\f]+ 一样 非空格,和 [^\n\t\r\f] 语法一样
\S+ 和 [^\\n\\t\\r\\f]+ 语法一样 \b 匹配以英文字母,数字为边界的字符串
\B 匹配不以英文字母,数值为边界的字符串 a|b|c 匹配符合a字符 或是b字符 或是c字符 的字符串
abc 匹配含有 abc 的字符串 (pattern) () 这个符号会记住所找寻到的字符串,是一个很实用的语法.第一个 () 内所找到的字符串变成 $1 这个变量或是 变量,第二个 () 内所找到的字符串变成 $2 这个变量或是 变量,以此类推下去.
/pattern/i i 这个参数表示忽略英文大小写,也就是在匹配字符串的时候,不考虑英文的大小写问题. \ 如果要在 pattern 模式中找寻一个特殊字符,如 “*“,则要在这个字符前加上 \ 符号,这样才会让特殊字符失效

*? +? ?? 为这三个数量词的非贪婪的类型

非懒惰                :
echo "ab2c121a" |perl -ne 'print $1 if /(.*)\d/;'   #print ab2c12
懒惰:
echo "ab2c121a" |perl -ne 'print $1 if /(.*?)\d/;'   #print ab

2.2 回溯引用和前后查找:

向前查找(?=..)  找字符串前面的内容,找到算成立             

echo "ab2c121a" |perl -ne 'print $1 if /(.*?)(?=2)/;'  #print ab
向后查找(?<=..)  找字符串后面的内容,找到算成立          

echo "ab2c121a" |perl -ne 'print $1 if /(?<=2)(.*)(?=2)/;' #print c1

负向-前/后 查找 (?!…)(?<!..)   找字符串前后的内容,如果不存在为真

echo "ab2c121a" |perl -ne 'print $1 if /(?<!--2)(c.*)/;'  #print 无
echo "ab2c121a" |perl -ne 'print $1 if /(?<!3)(c.*)/;'  #print c121a

 2.3 可选的修饰符

参考自:http://www.cnblogs.com/kevin-yuan/archive/2012/09/25/2702167.html

正则表达式中常用的模式修正符有i、g、m、s、x、e等。它们之间可以组合搭配使用。

它们的作用如下:

 //修正符:i 不区分大小写的匹配; 

         //如:"/abc/i"可以与abc或aBC或ABc等匹配;

//修正符:g表示全局匹配


    //修正符:m 将字符串视为多行,不管是那行都能匹配; 

       例://模式为:$mode="/abc/m"; 
         //要匹配的字符串为:$str="bcefg5e\nabcdfe" 
             //注意其中\n,换行了;abc换到了下一行; 
         //$str和$mode仍可以匹配,修正符m使得多行也可匹配; 
    //修正符:s 将字符串视为单行,换行符作为普通字符; 

       例://模式为:$mode="/pr.y/"; 
           //要匹配字符串为:$str="pr\ny"; 
           //两者不可匹配; . 是除了换行以外的字符可匹配; 
           //修改下模式为:$mode="/pr.y/s"; 
               //其中修正符s将\n视为普通字符,即不是换行; 
           //最后两者可以匹配; 
    //修正符:x 将模式中的空白忽略; 
    //修正符:A 强制从目标字符串开头匹配; 

         例://$mode="/abc/A"; 
           //可以与$str="abcsdfi"匹配, 
           //不可以与$str2="sdsdabc"匹配; 
           //因为$str2不是以abc开头; 
    //修正符:D 如果使用$限制结尾字符,则不允许结尾有换行; 

         例://模式为:$mode="/abc$/"; 
           //可以与最后有换行的$str="adshabc\n"匹配; 
           //元子符$会忽略最后的换行\n; 
           //如果模式为:$mode="/abc/D", 
           //则不能与$str="adshabc\n"匹配, 
           //修正符D限制其不可有换行;必需以abc结尾; 
    //修正符:U 只匹配最近的一个字符串;不重复匹配; 

         例: 
             如模式为: 
            $mode="/a.*c/"; 
            $str="abcabbbcabbbbbc" ; 
            preg_match($mode,$str,$content); 
            echo $content[0]; //输出:abcabbbcabbbbbc; 

            //如果$mode="/a.*c/";变成$mode="/a.*c/U"; 
             // 则只匹配最近一个字符串,输出:abc; 

//修正符:e 配合函数preg_replace()使用, 
           可以把匹配来的字符串当作正则表达式执行;  

将可选修饰符结合起来,其顺序是不重要的

关于/x 的作用: 例如: (/-? \d+ \.? \d* /x) 等同于 (/-?+.?/) 就是说/x修饰符允许你在模式中加入任何数量的空白,以方便阅读.

3.perl处理完后会给匹配到的值存在三个特殊变量名

$&, $`, $‘.匹配上的那部分字符串将自动存储在 $& 之中.变量 $1 中的值为 $' 中的内容,而 $& 为整个被匹配的部分,匹配部分的前一部分存放在 $` 之中,后一部分被存到 $’.另一种说法是, $` 中含有正则表达式引擎在匹配 成功前所找到的变量,而 $’ 为此模式还没有匹配的剩余部分.如果将这三个变量放在一起,你将得到原始字符串

4.perl中的扩展模式匹配

/pattern(?=string)/ 肯定和否定的匹配 ?= 和 ?-,这个在(?=)中的内容不会存到$&中

5.括号的特殊用法

6.更高级的优化

http://c20031776.blog.163.com/blog/static/684716252013624383887/

也是本文参考的博客!