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='hello
world';
$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'];
进一步理解
preg_match_all()通过这函数的最后一个参数,能够返回不同形式的数组:
$str= 'jiangsu (nanjing) nantong
guangdong (guangzhou) zhuhai
beijing (tongzhou) haidian';
$preg = '/^\s*+([^(]+?)\s\(([^)]+)\)\s+(.*)$/m';
preg_match_all($preg,$str,$arr,PREG_PATTERN_ORDER);
print_r($arr);
preg_match_all($preg,$str,$arr,PREG_SET_ORDER);
print_r($arr);
强大的正则替换回调
虽然
preg_replace() 函数能完成大多数的替换,但是假如你想更好的控制,可以使用回调,不用多说看例子:
$str = "china hello world";
$preg = '/\b(\w+)(\w)\b/';
function fun($m){
return $m[1].strtoupper($m[2]);
}
echo preg_replace_callback($preg,"fun",$str);