基础
定义
正则表达式是具有特殊语法结构的字符串
Regular Expression reg regexp
作用
- 表单验证
- 网络爬虫
函数库
- PCRE函数库
Perl兼容的正则表达式函数库
- POSIX(不推荐使用)
特点
- 语法结构复杂
- 执行效率低
相对于同功能的字符串函数而言
- 功能强大
语法
语法结构
/正则表达式/模式修饰符
定界符
- 正则表达式必须写在定界符里面
- 除了数字,字母和反斜杠的任意字符都可以做为定界符,一般用//
- 定界符必须成对出现
$pattern
模式规则的意思
$pattern="//";//定界符
$pattern="##";//有效
$pattern="11";//无效 定界符不能是数字
$pattern="AA";//无效 定界符不能是字母
$pattern="\\";//无效 定界符不能是反斜杠
$pattern="/#";//无效 定界符必须成对出现
原子
- 正则表达式中的最小原子
- 一个正则表达式若想有意义,则至少包含一个原子
- 普通字符
a
或1
或-
元字符(特殊的原子)
\s
匹配空格space
\S
匹配非空格\d
匹配数字decimal
\D
匹配非数字[^0-9]
\w
匹配单词(数字,大小写,下划线)[0-9a-zA-Z_]
\W
匹配非单词[^0-9a-zA-Z]
.
匹配任意字符
$subject="Hello, World";
$pattern='/\s/';//\s匹配空格\
//返回匹配结果的次数
//将返回结果赋值给第三个参数$matches
echo preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\S/";//\S大s 匹配非空格
echo preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$subject="This it test";
$pattern="#s#";//普通的原子
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$subject= "I am 18";
$pattern="/\d/";//匹配数字
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\D/";//匹配数字
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
function isNumber($value){
//思路:如果非数字匹配不到,则为纯数字
//\D匹配失败时,匹配对象为纯数字
$pattern="/\D/";
if (!preg_match_all($pattern,$value)){
return true;
}
return false;
}
$value='123adb';
$value='123';
$suc=isNumber($value);
echo $suc?"是数字":"不是数字";
$subject="I am_ 18.";
$pattern="/\w/";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\W/";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$subject="I am 18.";
$pattern="/./";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\./";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
转义符(escape)
-
\n
换行符newline -
\t
制表符 - 声明 双引号可以解析以上的的转义符,单引号不行
字符组
正字符组
- 可以在正字符组中给出多个原子,多个原子是"或"的关系
$pattern="/[is]/";//匹配字母i或者字母s
- 常用的字符组(匹配范围)
[0-9]
相当于\d
[a-z]
[A-Z]
负字符组
[^xxxxxx]
量词
- 用来修饰正则表达式出现的次数(数量)
- 语法
{n}
精确匹配==n==位 -
{n,}
开区间匹配 -
{n,m}
闭区间匹配,其中n,m都为正整数,n<m
$subject="This iis test";
$pattern="/i{2}/";
//匹配多位(,后面没有空格)
$pattern="/i{1,}/";
$pattern="/i{2,3}/";//匹配2位到3位
-
?
匹配0
或1
位{0,1}
-
*
匹配0
位或多位{0,}
-
+
匹配1
位或多位{1,}
$pattern="/s\s?/";//匹配"s"或"s空格" ?代表0或1位
$pattern="/s\s*/";//*匹配0到多位
$pattern="/s\s+/";//+匹配1到多位
//匹配手机号
//17375821270
//手机号是11位的数字 \d{11}
//手机号的第一位数字为1 1\d{10}
//13X 15X 17X 18X
//手机号第二位可能的数字是3578 [3578]
//手机号第三位也有号段(暂不考虑)
//177-1234-1234 1[3578]\d-?\d{4}-?\d{4}
//17712341234
//0177-1234-1234 0?1[3578]\d-?\d{4}-?\d{4}
//+86 0177-1234-1234 (暂时省略)
//匹配开头和结尾(边界),使用定位点符号 ^ $ ^0?1[3578]\d-?\d{4}-?\d{4}$
// /^正则表达式$/
//思路:
//1.首先分析目标字符串的规律(模式)
//2.将规律(模式)翻译成正则表达式
//3.验证
function isMobile($mobile){
$pattern="/^0?1[3578]\d-?\d{4}-?\d{4}$/";
if(preg_match($pattern,$mobile)){
return true;
}
return false;
}
$mobile="0173-7582-1270";
$suc=isMobile($mobile);
echo $suc?$mobile."手机号合法":$mobile."手机号非法";
//数字规律
//邮政编码
//身份证号
//区号
//QQ号
//....
定位点
- ==
^
== 匹配开头\A
- $ 匹配结尾
\Z
-
\b
匹配边界 -
\B
匹配非边界
//定位点
//^匹配开头
//$匹配结尾
$subject="This is test";
$pattern='/^T/';//匹配左侧边界
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/t$/";//匹配右侧边界
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/s\b/";//匹配右侧为边界的小写字母s
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\Bs\B/";//匹配非边界小写字母s
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
选择路径
-
|
或,a|b
$subject="This is test";
$pattern="/is|t/";//匹配is或者t
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
模式修饰符
-
i
"//i"
忽略大小写
$subject="This is test";
$pattern="/t/i";//忽略大小写,匹配字母t
//应用场景:对大小写不敏感时,使用模式修饰符i
//例如:<table>或者<TABLE> 都是有效的HTML标签
-
U
ungreedy
非贪婪模式(懒惰模式)- PHP正则默认是贪婪模式
- 贪婪:在满足条件的前提下尽可能多的匹配
- 可以混合使用
Ui
- ==
.*
== 贪婪模式 - ==
.*?
== 非贪婪模式(量词加问号限定死)
//贪婪模式
$subject="<td>zhangsan</td><td>lisi</td>";
$pattern="/<td>.+<\/td>/";//\转义 不然和定界符冲突
/*
* <pre>Array
(
[0] => Array
(
[0] => <td>zhangsan</td><td>lisi</td>
)
)
</pre>*/ //贪婪模式 因为 <td>zhangsan</td><td>lisi</td> zhangsan</td><td>lisi 也满足条件下尽可能多的匹配
//非贪婪模式
$pattern="/<td>.+<\/td>/U";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
/*
*
* Array
(
[0] => Array
(
[0] => zhangsan
[1] => lisi
)
)
*/ //非贪婪模式
捕获组
-
(XXXX)
描述正则表达式中的子表达式- 编号为0 的结果,匹配整个正则表达式
- 然后从1开始,按照小括号的顺序从左向右依次排序
- 引用
- 正向引用
- 在代码中(正则表达式之外)使用匹配成为正向引用
- 反向引用
- 语法
\number
number匹配结果对应的索引值 - 反向引用使用的是匹配结果,而不是正则表达式本身
- 语法
- 正向引用
// 03_group.php
// 捕获组 ()
// 假定该日期是一个生日
$subject = "2017-12-07";
// 日期格式分析:
// 年: 1900-现在 (19|20)\d{2} \d{4}
// 19\d{2}|200\d|201[0-7]
// 月: 01 02 .... 09 10 11 12
// 十位数: 0?[1-9]|1[0-2]
//
// 日: 01 ... 09
// 10 ... 19
// 20 ... 29
// 30 31
// 0?[1-9]|1[0-9]|2[0-9]|3[01]
// 0?[1-9]|[12][0-9]|3[01]
// 0?[1-9]|[12]\d|3[01]
// $pattern = "/(YYYY)-(MM)-(DD)/";
// $pattern = "/(YYYY)-((MM)-(DD))/";
$pattern = "/(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])/";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
-
(?:xxxx)
非捕获组
匹配函数
preg_match_all($pattern,$subject,$matches);
返回匹配的次数,二维数组
preg_match($pattern,$subject);
返回匹配的结果,一维数组
查找替换
preg_replace($pattern,$replacement,$matches)
和str_replace($search,$replacement,$matches)
$subject="This is test";
//将字符串中的空格替换成下划线
echo str_replace(" ","_",$subject)."<hr>";
$pattern="/\s/";
echo preg_replace($pattern,"_",$subject)."<hr>";
//声明:
//如果普通字符串函数与正则表达式函数能够完成同样的功能;
//则优先使用普通字符串函数(正则效率低)
$subject="This2 i4s te6st";
//将字符串中的数字替换成下划线
$pattern="/\d/";//匹配数字
echo preg_replace($pattern,"_",$subject)."<hr>";
//将html标签去掉
//<p>hello</p>
正则分割
array pre_split($pattern,$subject)
和array explode($delimiter,$string)
$subject="This is test";
$arr1=explode(" ",$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";
$pattern="/\s/";
$arr1=preg_split($pattern,$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";
//声明:
//如果普通字符串函数与正则表达式函数能够完成同样的功能;
//则优先使用普通字符串函数(正则效率低)
//根据右侧边界字母s进行分割
$pattern="/s\b/";
$arr1=preg_split($pattern,$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";
//普通函数达不到要求,必须要正则来写了
返回匹配模式的数组条码
preg_grep($pattern,$input);
//匹配数组元素
//grep =Global Regular ExPression
// 全局正则表达式
$pattern="/te/";
$input=array("time","term","team");
$arr=preg_grep($pattern,$input);
echo "<pre>";
print_r($arr);
echo "</pre>";