正则笔记

PHP正则操作相关

  • 元字符
元字符 说明 POSIX字符类 说明
 \d 任何一个数字字符,相当于[0-9]  [:alnum:]  任何一个字母或数字,相当于[a-zA-Z0-9]
 \D 任何一个非数字字符,相当于[^0-9]  [:alpha:] 任何一个字母,相当于[a-zA-Z] 
 \w 任何字母字符(大小写均可),数字字符,下划线_字符,相当于[a-zA-Z0-9_]  [:blank:] 空格或制表符,相当于[ \t] 
 \W 任何非字母字符(大小写均可),数字字符,下划线_字符,相当于[^a-zA-Z0-9_]  [:cntrl:] ASCII控制字符(ASCII 0到31,再加上ASCII 127)
 [\b]  回退(并删除)一个字符(Backspace键)  [:digit:] 任何一个数字,相当于[0-9] 
 \f  换页符  [:graph:] 和[:print:] 一样,但不包括空格
 \n 换行符   [:lower:] 任何一个小写字母,相当于[a-z] 
 \r 回车符   [:print:] 任何一个可打印字符 
 \t 制表符   [:punct:] 既不属于[:alnum:]也不属于[:cntrl:] 的任何一个字符,相当于
 \v 垂直制表符   [:space:] 任何一个空白字符,包括空格,相当于[\f\n\r\t\v ] 
 \s 任何一个空白字符,相当于[\f\n\r\t\v]   [:upper:] 任何一个大写字母,相当于[A-Z] 
 \S 任何一个非空白字符,相当于[^\f\n\r\t\v]   [:xdigit:]  任何一个十六进制数字,相当于[a-fA-F0-9]
 \x 十六进制数值前缀     
 \0(零) 八进制数值前缀     
    
匹配数量元字符 说明
+ 匹配至少一个,不配零个字符的情况,相当于{1,}
* 匹配零个或多个,相当于{0,}
? 匹配零个或一个,相当于{0,1}
    
贪婪型元字符 说明 懒惰型元字符 说明
* 贪婪型元字符,他们在进行匹配的时会从文本的开头一直匹配到末尾,而不是匹配到第一个时为止 *? 与贪婪型的行为模式恰好相反
+ +?
{n,} {n,}?
 
边界限定符 说明
\b (单词边界)\b用来匹配一个单词的开始或结尾
\B (单词边界)不匹配一个单词的边界(即非字母数字下划线)
^ (字符串边界)以什么开头
$ (字符串边界)以什么结尾
(?m) (分行匹配模式)分行匹配模式使得正则表达式引擎把行的分隔符当做一个字符串分隔符来对待.^不仅匹配正常的字符串开头,还将匹配行分隔符(换行符)后面的开始位置,$不仅匹配正常的字符串结尾,还将匹配行分隔符(换行符)后面的结束位置.在使用(?m)时,必须放在整个模式的最前面,此模式在下方有我的例子

 

  • 回溯引用的使用---回溯引用引用的是前面的划分的子表达式,当前面的子表达式匹配到的是word的时候,回溯引用也为word,他们是相同的
/*回溯引用(前后一致匹配,以及替换引用)*/
1
$sImageurl = 'http://i3.meishichina.com/http://i3.meishichina.com/attachment/good/2015/05/13/201505131431525637778.jpg'; 2 $sImageurl = preg_replace('/(http:\/\/\w{2}\.[a-z]+\.com\/)\1(.*)/','$1$2',$sImageurl); 3 echo $sImageurl;//http://i3.meishichina.com/attachment/good/2015/05/13/201505131431525637778.jpg
1 /*回溯引用(前后一致匹配)的测试*/
2 $sContent = file_get_contents('http://home.imeishi.com/blog/').'<h1>我是不是也会出来呢?</h6>';
3 preg_match_all('/<[hH][1-6]>.*?<\/[hH][1-6]>/', $sContent, $arMatch1);#未使用回溯引用
4 var_dump(end($arMatch1[0]));
5 preg_match_all('/<([hH][1-6])>.*?<\/\1>/', $sContent, $arMatch2);#使用回溯引用
6 var_dump(end($arMatch2[0]));
7 string(37) "<h1>我是不是也会出来呢?</h6>"
8 string(36) "<h5>随时随地,美食天下</h5>"

 

 

  • POSIX字符类的用法
 1 <?php 
 2 $sUrl = 'http://www.meishichina.com/mofang/class/yipinshicai/page/2/'; 
 3 preg_match_all('/[[:alnum:]]+/', $sUrl, $arMatch); 
 4 print_r($arMatch); 
 5 Array
 6 (
 7     [0] => Array
 8         (
 9             [0] => http
10             [1] => www
11             [2] => meishichina
12             [3] => com
13             [4] => mofang
14             [5] => class
15             [6] => yipinshicai
16             [7] => page
17             [8] => 2
18         )
19 
20 )
21 ?> 
  •  一个能在Unix/Linux和Windows上都能匹配空白行的正则
1 [\r]?\n[\r]?\n
  •  贪婪和懒惰
 1 /*测试贪婪型和懒惰型*/
 2 $sTxt = 'this offer is not available to cistomers living in <B>Ak</B> and <B>Hi</B>';
 3 preg_match_all('/<[Bb]>.+<\/[Bb]>/', $sTxt, $arMatch1);//贪婪型
 4 print_r($arMatch1);
 5 preg_match_all('/<[Bb]>.+?<\/[Bb]>/', $sTxt, $arMatch2);//懒惰型
 6 print_r($arMatch2);
 7 Array
 8 (
 9     [0] => Array
10         (
11             [0] => <B>Ak</B> and <B>Hi</B>
12         )
13 
14 )
15 Array
16 (
17     [0] => Array
18         (
19             [0] => <B>Ak</B>
20             [1] => <B>Hi</B>
21         )
22 
23 )
  •  php分行匹配注释
 1 匹配结果类似于这种的
 2      /**
 3      * 获取珍选下二级分类列表
 4      * @author    zhaoyingnan    2015/07/24 
 5      * @param    string    $param['classname']    一级分类名称
 6      * @param    int        $param['subid']    二级分类id
 7      * @param    int        $param['page']
 8      **/
 9     public function    secondClassifyList($param)
10 
11 //测试代码,可直接使用第二个,第一个是本人的文本中有特殊情况
12 $sContent = file_get_contents('/home/sunlibo/test/perl/zhen_action.php');
13 preg_match_all('/(?m)^[\s]*\/\*\*.*[\r]?\n([\s]*\*.*[\r]?\n)*.*/', $sContent, $arMatch1);
14 preg_match_all('/(?m)^[\s]*\/\*\*.*[\r]?\n([\s]*\*.*[\r]?\n)*[\s]*p.*/', $sContent, $arMatch2);
15 print_r($arMatch1[0]);
16 print_r($arMatch2[0]);
  •  子模式对于ip地址的匹配
 1 /*子模式对于ip地址的测试*/
 2 $sString = '[12.159.46.200],[0.0.0.0],[255.255.255.255],[192.179.0.256],[992.168.3.257],[2.992.992.105],[2.92.902.1]';
 3 preg_match_all('/((([\d]{1,2})|(1[\d]{2})|(2[0-4][\d])|(25[0-5]))\.){3}([\d]{1,2}|(1[\d]{2})|(2[0-4][\d])|(25[0-5]))/', $sString, $arMatch1);
 4 print_r($arMatch1[0]);
 5 preg_match_all('/(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))/', $sString, $arMatch2);
 6 print_r($arMatch2[0]);
 7 Array
 8 (
 9     [0] => 12.159.46.20
10     [1] => 0.0.0.0
11     [2] => 255.255.255.25
12     [3] => 192.179.0.25
13     [4] => 92.168.3.25
14 )
15 Array
16 (
17     [0] => 12.159.46.20
18     [1] => 0.0.0.0
19     [2] => 255.255.255.25
20     [3] => 192.179.0.25
21     [4] => 92.168.3.25
22 )

 

  • 前后查找(也称为零宽度匹配)

  前后查找中的前和后是与被查找的文本的相对位置而言的,左前右后原则;

  前后查找其实就是一个子表达式罢了,向前查找就是以?=开头的子表达式,向后查找就是已?<=开头的子表达式;

  前后查找匹配的内容并不会出现在最终结果里面;

  ?!是对向前查找的取非;

  ?<!是对向后查找的取非.

 1 /*向前(后)查找匹配测试*/
 2 $sCss = '
 3     .bar-box li.bar-box-item-0{background:#848484}
 4     .bar-add .bar-text{background:#ff8f30;color:#ddd;width:36px}
 5     li.bar-box-item-1{background:#919191}
 6     li.bar-box-item-2{background:#9d9d9d}
 7     li.bar-box-item-3{background:#a9a9a9}
 8     bar-text{background:#ff8721;color:#fff}
 9     ';
10 //向前匹配类似于.bar-box 的内容,最后结果不包括空格
11 preg_match_all('/[.\w-]+(?=\s)/', $sCss, $arMatch1);
12 var_dump(current($arMatch1));
13 //向后匹配类似于#a9a9a9的颜色内容,但是最终结果不包含#
14 preg_match_all('/(?<=#)[a-fA-F\d]{3,6}/', $sCss, $arMatch2);
15 print_r(current($arMatch2));
16 
17 array(2) {
18   [0]=>
19   string(8) ".bar-box"
20   [1]=>
21   string(8) ".bar-add"
22 }
23 Array
24 (
25     [0] => 848484
26     [1] => ff8f30
27     [2] => ddd
28     [3] => 919191
29     [4] => 9d9d9d
30     [5] => a9a9a9
31     [6] => ff8721
32     [7] => fff
33 )
 1 $sPrice = '
 2     ABC01:  $23.45
 3     HGG42:  $5.31
 4     CFMX1:  $899.00
 5     XTC99:  $69.96
 6     ZCC94:  $6
 7     TOTAL ITEMS FOUND:  4
 8     ';
 9 //向后匹配价格,最终结果不能包含$
10 preg_match_all('/(?<=\$)[\d]+[.]?[\d]*/', $sPrice, $arMatch);
11 print_r(current($arMatch));
12 
13 Array
14 (
15     [0] => 23.45
16     [1] => 5.31
17     [2] => 899.00
18     [3] => 69.96
19     [4] => 6
20 )

 

 

  • 正则表达式里面的条件判断

  回溯引用判断:(?(1)\s*<\/a>)只用?(1)为真的时候才会执行其后面的匹配\s*<\/a>,否则不往后匹配

 1 /*正则表达式条件判断测试*/
 2 //回溯引用判断
 3 $sHtml = '
 4     <ul>
 5     <li> <a title="木木家常菜" target="_blank" href="http://home.meishichina.com/space-8271699.html"> <img width=540 height=200  class="imgLoad" src="http://static.meishichina.com/v6/img/blank.gif"  data-src="http://i3.meishichina.com/attachment/magic/2015/07/21/20150721110355948431183.jpg"> </a> </li>
 6     <li> <a title="叶子的小厨" target="_blank" href="http://home.meishichina.com/space-5987665.html"> <img width=540 height=200  class="imgLoad" src="http://static.meishichina.com/v6/img/blank.gif"  data-src="http://i3.meishichina.com/attachment/magic/2015/07/21/20150721110324961950668.jpg"> </a> </li>
 7     <li> <img width=540 height=200  class="imgLoad" src="http://static.meishichina.com/v6/img/blank.gif"  data-src="http://i3.meishichina.com/attachment/magic/2015/07/21/20150721110205697095131.jpg"> </a></li>
 8     </ul>
 9     ';
10 preg_match_all('/(<a[\s]*[^>]+>\s*)?<img[\s]*[^>]+\/?>(?(1)\s*<\/a>)/', $sHtml, $arMatch);
11 print_r($arMatch);
12 
13 Array
14 (
15     [0] => <a title="木木家常菜" target="_blank" href="http://home.meishichina.com/space-8271699.html"> <img width=540 height=200  class="imgLoad" src="http://static.meishichina.com/v6/img/blank.gif"  data-src="http://i3.meishichina.com/attachment/magic/2015/07/21/20150721110355948431183.jpg"> </a>
16     [1] => <a title="叶子的小厨" target="_blank" href="http://home.meishichina.com/space-5987665.html"> <img width=540 height=200  class="imgLoad" src="http://static.meishichina.com/v6/img/blank.gif"  data-src="http://i3.meishichina.com/attachment/magic/2015/07/21/20150721110324961950668.jpg"> </a>
17     [2] => <img width=540 height=200  class="imgLoad" src="http://static.meishichina.com/v6/img/blank.gif"  data-src="http://i3.meishichina.com/attachment/magic/2015/07/21/20150721110205697095131.jpg">
18 )
19 //可以看到最后一个并没有匹配</a>

 

  前后条件判断:(?(?=-)-[\d]+)只有当(?(?=-))为真的时候-[\d]+才会执行

 1 //前后查找条件判断,不匹配4567-这种的
 2 $sNumber = '
 3     1232
 4     1235-4565
 5     4567-
 6     5678
 7     4569-789777
 8     03123611656
 9     0312-3611656
10     ';
11 preg_match_all('/([\d]{11})|([\d]{4}(?(?=-)-[\d]+))/', $sNumber, $arMatch);
12 print_r(current($arMatch));
13 
14 Array
15 (
16     [0] => 1232
17     [1] => 1235-4565
18     [2] => 5678
19     [3] => 4569-789777
20     [4] => 03123611656
21     [5] => 0312-3611656
22 )

 

  亲,自己研究下吧,(*^__^*) 

 1 //前后查找条件判断,不匹配带括号这种的电话号码
 2 $sPhone = '
 3     010-3722069
 4     0103722069
 5     (010)3722069
 6     (0315)3611656
 7     03123611656
 8     0312-3611656
 9     ';
10 preg_match_all('/\s*[^\(]((\d{10,11})|(\b[\d]{3,4}(?(?=-)-[\d]+)\b))/', $sPhone, $arMatch2);
11 print_r(current($arMatch2));
12 
13 Array
14 (
15     [0] => 
16     010-3722069
17     [1] => 
18     0103722069
19     [2] => 
20     03123611656
21     [3] => 
22     0312-3611656
23 )

  但是其实上面的方法并不是很好的,仔细查看后就会发现上面那个也会010-37220618这个位数多于正确的电话号码,也会匹配0318)3787353中的0318,012)3722061中的012,所以最好采用下面的正则

 1 $sTel = ' 
 2     010-3722069
 3     010-37220618
 4     0103722068
 5     03123817117
 6     03163611656
 7     0312-3611655
 8     (0315)3787354
 9     0318)3787353
10     012)3722061
11     03163)611656
12     ';
13 preg_match_all('/[\s]*((\b[\d]{10,11}\b)|(\b[\d]{3}[-]\d{7}\b)|(\b[\d]{4}[-][\d]{7}\b))/', $sTel, $arMatch3);
14 print_r($arMatch3[0]);
15 
16 Array
17 (
18     [0] => 
19     010-3722069
20     [1] => 
21     0103722068
22     [2] => 
23     03123817117
24     [3] => 
25     03163611656
26     [4] => 
27     0312-3611655
28 )

 

手机号码正则

 1 <?php
 2 var_dump(_validateMobile(17091310244));
 3 var_dump(_validateMobile(14591310244));
 4 var_dump(_validateMobile(18911937250));
 5 function _validateMobile($iPhone)
 6 {
 7     //电信号段:133/153/180/181/189/175/177
 8     //联通号段:130/131/132/155/156/185/186/145/176
 9     //移动号段:134/135/136/137/138/139/150/151/152/157/158/159/182/183/184/187/188/147/178
10     //虚拟运营商:170
11     if($iPhone)
12     {
13         preg_match('/^13\d{9}$|^14[57]\d{8}$|^15[012356789]\d{8}$|^17[05678]\d{8}$|^18\d{9}$/', $iPhone, $arMatch); 
14         if($arMatch)
15             return 1;
16     }
17     return 0;
18 }

 

posted @ 2015-07-02 16:33  zhaoyingnan911  阅读(309)  评论(0编辑  收藏  举报