PHP 正则表达式(PCRE)
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
PHP 中我们可以使用 PCRE 扩展来匹配字符串的模式。
PCRE 函数
|
函数 |
描述 |
|
执行一个正则表达式搜索和替换 |
|
|
返回匹配模式的数组条目 |
|
|
返回最后一个PCRE正则执行产生的错误代码 |
|
|
执行一个全局正则表达式匹配 |
|
|
执行一个正则表达式匹配 |
|
|
转义正则表达式字符 |
|
|
执行一个正则表达式搜索并且使用一个回调进行替换 |
|
|
执行一个正则表达式搜索并且使用一个回调进行替换 |
|
|
执行一个正则表达式的搜索和替换 |
|
|
通过一个正则表达式分隔字符串 |
不同于传统的正则表达式写法,在PHP中 需要使用定界符来界定正则表达式字符串
通常情况下,定界符为”/” 因此需要在正则表达式开始和末尾都加上”/” 即下面红色部分
例如: $regex = “/<title>.+<\/title>/“
用于匹配html中的title标签
因为定界符为”/” 所以需要对</title>标签中的”/”进行转义,即在”/”前面加上”\”
或者使用自定义定界符, 所有非字母数字,非空白字符(除了反斜杠”\”)都可以作为定界符,但必须成对出现
例如:{regex},#regex#,<regex>,%regex%等都是可行的
$regex = ‘”{<title>.+</title>}“或者是$regex = “%<title>.+</tilte>%“
因为不是使用”/”作为定界符,所以</title>标签中的”/”不需要进行转义
虽然PHP中可以自定义正则表达式定界符,但应当避免使用正则表达式元字符作为定界符例如
. * + ? ^ $ 等
或者是{ 大 } [ 中 ] ( 小 ) <尖>等括号
以及其他常用符号例如: @ # ! ” 等
推荐使用%作为定界符
要判断文本中是否包含某个字符串,可使用preg_match 或 preg_match_all
Preg_match 函数
语法:
int preg_match ( string $pattern , string $subject ,[ array &$matches ],[ int $flags = 0],[ int $offset = 0 ] )
返回值: 0 或 1 发生错误时返回 False
参数:
|
参数 |
含义 |
|
$pattern |
(必须)用于匹配的正则表达式模式,string类型 |
|
$subject |
(必须)待匹配的文本字符串,string类型 |
|
$matches |
(可选)参数$matches,用于保存匹配的结果 需要注意的是,$matches 始终返回一个只有1个元素的数组,即便是只匹配到1个或者0个 即:要获取匹配结果的话需使用 $matches[0] |
|
$flags |
(可选,不常用) $flags 的有效值为: PREG_OFFSET_CAPTURE 如果设置了该参数,将会修改匹配结果$matches数组结构, 即$matches[0][0]为匹配结果$matches[0][1]为匹配结果在$subject中的起始位置(以字节为单位计算) |
|
$offset |
(可选,不常用)通常情况下都是从目标字符串的开始位置开始查找, 设置 $offset 可以指定从目标字符串的某个位置开始搜索(以字节为单位计算) |
preg_match 只会匹配第1个符合条件的字符串
例如:
$str = “我的手机号是:10086和10089还有186189″;
$regex = “%\d+%”;
$CountMatches = preg_match($regex,$str,$matches);
echo(“共找到“.$CountMatches.“个“);
var_dump($matches);
echo($matches[0]);
输出结果为:
在匹配到第1个符合条件的字符串后,preg_match就会停止匹配,
即便如此$matches 依然是个数组
preg_match_all 函数
语法:
int preg_match_all ( string $pattern , string $subject ,[ array &$matches ],[ int $flags = 0],[ int $offset = 0 ] )
返回值: 0 或 n 发生错误时返回 False
参数:
|
参数 |
含义 |
|
$pattern |
(必须)用于匹配的正则表达式模式,string类型 |
|
$subject |
(必须)待匹配的文本字符串,string类型 |
|
$matches |
(可选)参数$matches,用于保存匹配的结果 需要注意的是preg_match_all 的 $matches 参数默认返回一个只有1个元素的二维数组, 即便是匹配到1个,n个,或者0个,$matches 默认都是1个二维数组 即:$matches[0]是一个包含所有匹配结果的数组, |
|
$flags |
(可选,不常用) $flags 的有效值为: PREG_PATTERN_ORDER ,PREG_SET_ORDER , PREG_OFFSET_CAPTURE
如果设置了该参数,将会修改匹配结果$matches数组结构,具体结构请看后面的解析 |
|
$offset |
(可选,不常用)通常情况下都是从目标字符串的开始位置开始查找, 设置 $offset 可以指定从目标字符串的某个位置开始搜索(以字节为单位计算) |
preg_match_all 语法与 preg_match 类似 不同之处在于preg_match 在匹配到第1个结果时会停止匹配 ,
而preg_match_all 能遍历整个目标字符串,并返回完整的匹配次数
需要注意的是preg_match_all 的 $matches 参数默认返回一个只有1个元素的二维数组,即便是只匹配到1个,n个,或者0个
即:$matches[0]是一个包含所有匹配结果的数组,
例如:
$str = “我的手机号是:10086和10089还有186189″;
$regex = “%\d+%”;
$matchCount = preg_match_all($regex,$str,$matches);
echo(“共找到“.$matchCount);
var_dump($matches);
var_dump($matches[0]);
输出结果为:
共 找 到 3 个
array(l) { [ 0 ] = > a rray(3) { [ 0 ] = > string ( 5 ) ” 10086 ” [ 1 ] = > string(S) ” 10089 ” [ 2 ] = > string ( 6 ) ” 186189 ‘ } }
array(3) { [ 0 ] = > string(S) ” 10086 ” [ 1 ] = > string(S) ” 10089 ” [ 2 ] = > string(6) ” 186189 ” }
注意查看$matches 与 $matches[0] 的区别
即使只匹配到1个结果,$matches 依然为一个二维数组,要获取匹配结果需要使用 $matches[0][0]
例如:
$str = “我的手机号是:10086″;
$regex = “%\d+%”;
$matchCount = preg_match_all($regex,$str,$matches);
echo(“共找到“.$matchCount.“个“);
var_dump($matches);
echo(“第1个匹配结果为:”.$matches[0][0]);
输出结果为:
共 找 到 1 个
array(l) { [ 0 ] => array(l) { [ 0 ] => string ( 5 ) ” 10086 ” } }
第 1 个 匹 配 结 果 为 : 10086
要获取第一个匹配结果请使用$matches[0][0],第二个匹配结果为$matches[0][1] , 依次类推
例如:
$str = “我的手机号是:10086和10089还有186189″;
$regex = “%\d+%”;
$matchCount = preg_match_all($regex,$str,$matches);
echo(“共找到“.$matchCount);
var_dump($matches);
echo(“第1个匹配结果为:”.$matches[0][0]);
echo(“第2个匹配结果为:”.$matches[0][1]);
echo(“第3个匹配结果为:”.$matches[0][2]);
输出结果为:
共 找 到 3 个
array(l) { [ 0 ] => a rray(3) { [ 0 ] => string ( 5 ) ” 10086 ” [ 1 ] => string(S) ” 10089 ” [ 2 ] => string ( 6 ) ” 186189 ‘ } }
第 1 个 匹 配 结 果 为 : 10086
第 2 个 匹 配 结 果 为 : 10089
第 3 个 匹 配 结 果 为 : 186189
关于 preg_match_all 函数 $flag 参数的解析
$flags 的有效值为: PREG_PATTERN_ORDER ,PREG_SET_ORDER , PREG_OFFSET_CAPTURE
1.当 $flag 设置为 PREG_PATTERN_ORDER 时 $matches 的返回结果为只有1个元素的二维数组
例如:
$str = “我的手机号是:10086和10089还有186189″;
$regex = “%\d+%”;
$CountMatches = preg_match_all($regex,$str,$matches,PREG_PATTERN_ORDER);
echo(“共找到“.$CountMatches);
var_dump($matches);
输出结果为:
共 找 到 3 个
array(l) { [ 0 ] => a rray(3) { [ 0 ] => string ( 5 ) ” 10086 ” [ 1 ] => string(S) ” 10089 ” [ 2 ] => string ( 6 ) ” 186189 ‘ } }
2.当$flag 设置为PREG_SET_ORDER 时 $matches 的返回结果为包含n个元素的二维数组
例如:
$str = “我的手机号是:10086和10089还有186189″;
$regex = “%\d+%”;
$CountMatches = preg_match_all($regex,$str,$matches,PREG_SET_ORDER);
echo(“共找到“.$CountMatches.“个“);
var_dump($matches);
echo(“第1个匹配结果为:”.$matches[0][0]);
echo(“第2个匹配结果为:”.$matches[1][0]);
echo(“第3个匹配结果为:”.$matches[2][0]);
输出结果为;
共 找 到 3 个
array(3) { [ 0 ] => array(l) { [ 0 ] => string ( 5 ) ” 10086 ” } [ 1 ] => array(l ) { [ 0 ] => string(S) ” 10089 ” } [ 2 ] => array(l) { [ 0 ] => stnng(6) ” 186189 ” } }
第 1 个 匹 配 结 果 为 : 10086
第 2 个 匹 配 结 果 为 : 10089
第 3 个 匹 配 结 果 为 : 186189
此时获取第1个匹配结果为:$matches[0][0]
而要获取第2个匹配结果应使用: $matches[1][0] 第3个使用匹配结果应使用$matches[2][0]依次类推
3.当$flag 设置为 PREG_OFFSET_CAPTURE 时 $matches 的结果如下, 这种用法非常少见, 因此不作解释
例如:
$str = “我的手机号是:10086和10089还有186189″;
$regex = “%\d+%”;
$CountMatches = preg_match_all($regex,$str,$matches,PREG_OFFSET_CAPTURE);
echo(“共找到“.$CountMatches.“个<br/>”);
var_dump($matches);
输出结果为:
共 找 到 3 个
array(l) { [ 0 ] => a rray(3) { [ 0 ] => array(2) { [ 0 ] => string(S) ” 10086 ” [ 1 ] => Int(1 9 ) } [ 1 ] => array(2) { => string(S) ” 10089 ” [ 1 ] => Int(27) } [ 2 ] => array(2) { => string(6) ” 186189 ” [ 1 ] => Int(38) } } }
特别需要注意的是: preg_match( ) 与 preg_match_all( ) 的返回值都是,匹配的次数,而不是匹配的内容
所以使用 $matches = preg_match( $regex , $string ) 并不能获取到匹配的内容
要获取匹配的内容应该提供 $matches 参数 用于保存 匹配的内容