最近使用 PHP 写了一个应用,主要是正则表达式的处理,趁机系统性的学习了相应知识。
这篇文章的写作方式不是讲理论,而是通过具体的例子来了解正则,这样也更有实践性,在此基础上再去看正则表达式的基本概念会更有收获。
禁止分组的捕获
在正则中分组很有用,可以定义子模式,然后可以通过后向引用来引用分组的内容,但是有的时候仅仅想通过分组来进行范围定义,而不想被分组来捕获,通过一个例子就能明白:
$str = "http://www.google.com";$preg= "/http://///w+/./w+.(?:net|com|cn)+/is";$preg2= "/http://///w+/./w+.(net|com|cn)+/is";preg_match($preg,$str,$arr);preg_match($preg2,$str,$arr2);
当模式中出现?:表示这个括号的分组不会被引用,运行下例子就能明白。
preg_match() 和 preg_match_all() 的区别
preg_match() 在匹配模式的时候匹配到一次就结束,而 preg_match_all() 则进行全局匹配,通过一个例子就能明白:
$str='hello world china';$preg="//w+/s/is";preg_match($preg,$str,$arr);print_r($arr);preg_match_all($preg,$str,$arr);print_r($arr);
正确理解 $ 和 ^
先说一个正则,为了匹配是否是手机号:
$str = "13521899942a";$preg="/1[/d]{3,15}/is";if (preg_match($preg,$str,$arr)) { echo "ok";}
虽然字符串中有一个英文字母,但是这个子模式却匹配了,原因就在于模式匹配到后就结束了,不会再去寻找英文字母,为了解决这问题 $ 和 ^ 就发挥作用了,比如让字符串的开始和结尾必须匹配一定的模式,修改如下:
$str = "13521899942a";$preg="/1[/d]{3,15}$/is";if (preg_match($preg,$str,$arr)) { echo "ok";}
$ 和 ^ 的跨行模式
默认的情况下,$ 和 ^ 只会匹配完整段落的开始和结尾,但是通过改变选项,允许匹配文本的每一行的开始和结尾,通过下面的例子就能明白
$str='helloworld';$preg='//w+$/ism';//$preg='/(?m)/w+$/is';preg_match_all($preg,$str,$arr);print_r($arr);
分组命名
在正则中通过括号分组后,可以使用 /1,/2 这样的数字进行后向引用,但是假如正则中模式太多,在使用的时候就会比较混乱,这时候可以采用分组命名来进行引用,看个例子:
$str ="email:ywdblog@gmail.com;";preg_match("/email:(?<email>/w+?)/is", $str, $matches);echo $matches["email"] . "_" . $matches['no'];
懒惰模式
正则在匹配的时候是贪婪的,只要符合模式就会一直匹配下去,下面的例子,匹配到的文本是 <h2>hello</h2><h2>world</h2>
$str = "<h2>hello</h2><h2>world</h2>";$preg = "/<h2>.*<//h2>/is";preg_match($preg,$str,$arr);print_r($arr);
新闻热点
疑难解答