使用正则表达式的目的是为了实现比字符串处理函数更加灵活的处理方式,因此跟字符串处理函数一样,其主要用来判断子字符串是否存在、字符串替换、分割字符串、获取模式子串等。

    PHP使用PCRE库函数来进行正则处理,通过设定好模式,然后调用相关的处理函数来获取匹配结果。

    preg_match用来执行一个匹配,可以简单的用来判断模式是否匹配成功,或者取得一个匹配结果,它的返回值是否匹配成功的次数0或者1,在匹配到1次以后就会停止搜索。

$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern,$subject,$matches);
print_r($matches);  //结果为:Arrary([0] => def)

    上面的代码简单的执行了一个匹配,简单地判断def是否能匹配成功,但是正则表达式的强大的地方是进行模式匹配,因此更多时候,会使用模式。

$subject = "abcdef";
$pattern = '/a(.*?)d/';
preg_match($pattern,$subject,$matches);
print_r($matches);  //结果为:Arrary ([0] => abcd[1]=>bc)
    通过正则表达式可以匹配一个模式,得到更多的有用的数据。

//使用preg_match匹配字符串中的邮箱,并输出该邮箱
<?php 
$subject = "my email is spark@imooc.com";
$pattern = '/[\w\-]+@\w+\.\w+';
preg_match($pattern,$subject,$matches);
echo $matches[0];  //输出结果为:spark@imooc.com

  查找所有匹配结果:preg_match只能匹配一次结果,但很多时候我们需要匹配所有的结果,preg_match_all可以循环获取一个列表的匹配结果数组。

$p = "|<[^>]+>(.*?)</[^>]+>|i";
$str = "<b>example:</b><div align = left>this is a text</div>";
preg_match_all($p,$str,$matches);
print_r($matches);
    可以使用preg_match_all匹配一个表格中的数据:

$p = "/<tr><td>(.*?)<\/td>\s*<td>(.*?)<\/td>\s*<\/tr>/i";
$str = "<table> <tr><td>Eric</td><td>25</td></tr><tr><td>John</td><td>26</td></tr></table>";
preg_match_all($p,$str,$matches);
print_r($matches);
    $matches结果排序为$matches[0]保存完整模式的所有匹配,$matches[1]保存第一个子组的所有匹配,以此类推。

//使用preg_match_all匹配所有li标签中的数据
<?php
$str = "<ul>
                  <li>item 1</li>
                  <li>item 2</li>
            </ul>";
$p = "/<li>(.*)<\/li>/i";  //解释下这个正则匹配所有li中的数据 //后面的i表示不区分大小写,<li>(.*)<\/li>表示li标签内的匹配的()内的数量有多少,括号内的,表示所有单字符,*表示数量为0个或者多个。也就是li标签内有字符就显示出来
preg_match_all($p,$str,$matches);
print_r($matches[1]);
//输出结果为:Array
(
    [0] => item 1
    [1] => item 2
)
    正则表达式的搜索和替换:正则表达式的搜索与替换在某些方面具有重要用途,比如调整目标字符串的格式,改变目标字符串中匹配字符串的顺序等。

    例如我们可以简单的调整字符串的日期格式:

$string = 'April 15,2014';
$pattern = '/(\w+)(\d+),(\d+)/i';
$replacement = '$3,${1}$2';
echo preg_replace($pattern,$replacement,$string);  //结果为:2014,April 15
    其中$(1)与$1的写法是等效的,表示第一个匹配的字串,$2代表第二个匹配的。

    通过复杂的模式,我们可以更加精确的替换目标字符串的内容。

$patterns = array ('/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/',
                   '/^\s*{(\w+)}\s*=/');
$replace = array ('\3/\4/\1\2', '$\1 =');//\3等效于$3,\4等效于$4,依次类推
echo preg_replace($patterns, $replace, '{startDate} = 1999-5-27'); //结果为:$startDate = 5/27/1999
//详细解释下结果:(19|20)表示取19或者20中任意一个数字,(\d{2})表示两个数字,(\d{1,2})表示1个或2个数字,(\d{1,2})表示1个或2个数字。^\s*{(\w+)}\s*=表示以任意空格开头的,并且包含在{}中的字符,并且以任意空格结尾的,最后有个=号的。
    用正则替换去掉多余的空格与字符:

$str = 'one     two';
$str = preg_replace('/\s+/', ' ', $str);
echo $str; // 结果改变为'one two'
//将目标字符串$str中的文件名替换后增加em标签,例如index.php要替换成<em>index.php</em>。
<?php
$str = '主要有以下几个文件:index.php, style.css, common.js';
//将目标字符串$str中的文件名替换后增加em标签
$p = '/\w+\.\w+/i';
$str = preg_replace($p,'<em>$0</em>',$str);
echo $str;
//结果为:主要有以下几个文件:<em>index.php</em>, <em>style.css</em>, <em>common.js</em>
    正则匹配中常用案例:正则匹配常用在表单验证上,一些字段会有一定的格式要求,比如用户名一般都要求必须是字母、数字或下划线组成,邮箱、电话等也都有自己的规则,因此使用正则表达式可以很好的对这些字段进行验证。

    一般的用户注册页,都怎样对字段进行验证:

//如何对用户注册信息进行验证。尝试修改各字段的值来观察正则表达式的验证效果。
<?php
$user = array(
    'name' => 'spark1985',
    'email' => 'spark@imooc.com',
    'mobile' => '13312345678'
);
//进行一般性验证
if (empty($user)) {
    die('用户信息不能为空');
}
if (strlen($user['name']) < 6) {
    die('用户名长度最少为6位');
}
//用户名必须为字母、数字与下划线
if (!preg_match('/^\w+$/i', $user['name'])) {
    die('用户名不合法');
}
//验证邮箱格式是否正确
if (!preg_match('/^[\w\.]+@\w+\.\w+$/i', $user['email'])) {
    die('邮箱不合法');
}
//手机号必须为11位数字,且为1开头
if (!preg_match('/^1\d{10}$/i', $user['mobile'])) {
    die('手机号不合法');
}
echo '用户信息验证成功';
//输出结果为:用户信息验证成功