0%

PHP基础学习--正则表达式

正则表达式用于判定一串文本中是否包含特定的片段或者符合某种规则,在各种程序中都有着至关重要的作用。
比如,使用内置的preg_match函数查看一段字符串中是否包含了“苹果”:

1
2
3
4
5
6
7
<?php
$p="苹果";
$str="我喜欢吃苹果";
if(preg_match($p,$str)){
echo "匹配成功";
}
?>

基本语法

PCRE库函数中,正则匹配模式使用分隔符元字符组成;
分隔符可以是非数字非反斜线非空格任意字符
经常使用的分隔符是正斜线(/)hash符号(#) 以及取反符号(~);
例:

/foo bar/
#^[^0-9]$#
~php~

如果模式中包含分隔符,则分隔符需要使用反斜杠(\)进行转义。/http:\/\//

如果模式中包含较多的分割字符,建议更换其他的字符作为分隔符,也可以采用preg_quote进行转义。
例:$p = 'http://';$p = '/'.preg_quote($p, '/').'/';

分隔符后面可以使用模式修饰符,模式修饰符包括:i, m, s, x等,例如使用i修饰符可以忽略大小写匹配;

特殊字符

构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

字符 说明
$ 匹配输入字符串的结尾位置。如果设置了RegExp对象的Multiline属性,则$也匹配‘\n’或‘\r’。要匹配$字符本身,请使用$。
() 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。
* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
. 匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 .。
[ 标记一个中括号表达式的开始。要匹配 [,请使用 [。
? 匹配前面的表达式零次或者一次,或指明一个非贪婪限定符
|转义字符
^ 输入字符串的开始位置,除非在方括号表达式中使用,此时表示不接受此类字符集合。
{ 标记限定符表达式的开始
\w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。
\W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有或+或?或{n}或{n,}或{n,m}共6种。
其中`
、+和?限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?`就可以实现非贪婪或最小匹配。

字符 说明
* 匹配前面的子表达式零次或者多次
+ 匹配前面的表达式一次或者多次(贪婪模式)
? 匹配前面的表达式零次或者一次(懒惰模式)
{n} n为一个非负整数,表示匹配的精确的限定次数
{n,} n为一个非负整数,表示至少匹配n次
{n,m} n,m均为非负整数,其中n<=m,表示至少匹配n次之多匹配m次。

非打印字符

字符 说明
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。

preg_match

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

1
2
3
4
5
6
7
<?php
$subject = "my email is spark@imooc.com";
//在这里补充代码,实现正则匹配,并输出邮箱地址
$pattern = '/[a-z]+@[a-z}+\.[a-z]+/';
preg_match($pattern,$subject,$matches);
print_r($matches[0]);
?>

preg_match_all

循环获取一个列表的匹配结果数组。

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$str = "
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
";
//在这里补充代码,实现正则匹配所有li中的数据
$p="/<li>(.*?)<\/li>/i";
preg_match_all($p,$str,$matches);
print_r($matches[1]);
?>

$matches结果排序为$matches[0]保存完整模式的所有匹配, $matches[1]保存第一个子组的所有匹配,以此类推。

搜索和替换

正则表达式的搜索与替换在某些方面具有重要用途,比如调整目标字符串的格式,改变目标字符串中匹配字符串的顺序等。
例如我们可以简单的调整字符串的日期格式:

$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代表第二个匹配的。

1
2
3
4
5
6
<?php
$str = '主要有以下几个文件:index.php, style.css, common.js';
//将目标字符串$str中的文件名替换后增加em标签
$str = preg_replace('/\w+\.\w+/i','<em>$0</em>',$str);
print_r($str);
?>

实例:验证用户信息填写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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 '用户信息验证成功';