正则表达式是一种规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本。
在php里,我们使用preg_match
进行正则表达式匹配,
该函数原型:
int preg_match( string $pattern, string $subject [, array &$matches ] )
$pattern
即表达式,$subject
为需要匹配的文本,$matches
用来存放匹配结果,
当匹配成功时,函数返回1
,否则返回0
。
举个例子:
我用过一个api(网页接口),它可以用来获取天气信息,但它总是返回类似5 ~ 19℃
的温度信息,不方便直接使用,所以我要用正则表达式把它匹配出来。
$temp = '5 ~ 19℃';
正则表达式部分常用字符:
\
为转义字符,也可加在特殊字符前,使其成为普通文本,如\\
将匹配\
,而后面的\
不会被当成特殊字符。
[xyz]
:与括号中字符的其中一个字符匹配,如[abc]
匹配plain
中的a
\d
为匹配任意一个十进制数字,等价于[0-9]
\w
匹配任意一个数字、字母、或下划线,等价于[0-9a-zA-Z]
+
匹配1次或多次其前的文本
?
:匹配0次或多次其前的文本。
*
:匹配1次或多次其前的文本。
{m, n}
:至少匹配m次,至多匹配n次其前的文本,n可省略,即至少匹配m次。
…有兴趣的同学可以搜索一下正则表达式的更多规则
因为天气温度不可能为空,且最多用三个字符表示(负号、0-9),所以正则表达式写成:/([0-9\-]{1,3}) ~ ([0-9\-]{1,3})℃/
,头尾的两个斜杠是不能忽略的,斜杠之间的文本才是实际的正则表达式文本。
if(preg_match('/([0-9\-]{1,3}) ~ ([0-9\-]{1,3})℃/', $temp, $match)) {
var_dump($match);
} else {
echo '未匹配到天气信息';
}
会有如下输出:
array(3) {
[0]=>
string(9) "5 ~ 19℃"
[1]=>
string(1) "5"
[2]=>
string(2) "19"
}
从结果来看,
数组第一个成员是匹配到的文本,
后面都是子文本,即表达式中用括号匹配的那部分文本。
不过,preg_match
只能匹配一次,
简单来说,就是如果文本里有两个温度信息,那只能匹配出第一个信息。
要改变这现状,就要用preg_match_all
:
用法和preg_match
一致,就多了第四个参数flag
,不过一般情况下用不到该参数。
还有就是,preg_match_all
的返回值是匹配次数。
比如现在有三个温度信息,他们之间有逗号分开:
$temp = '5 ~ 19℃,8 ~ 13℃,10 ~ 15℃';
if(preg_match_all('/([0-9\-]{1,3}) ~ ([0-9\-]{1,3})℃/' ,$temp, $match)) {
var_dump($match);
} else {
echo '未匹配到天气信息';
}
这时会输出如下信息:
array(3) {
[0]=>
array(3) {
[0]=>
string(9) "5 ~ 19℃"
[1]=>
string(9) "8 ~ 13℃"
[2]=>
string(10) "10 ~ 15℃"
}
[1]=>
array(3) {
[0]=>
string(1) "5"
[1]=>
string(1) "8"
[2]=>
string(2) "10"
}
[2]=>
array(3) {
[0]=>
string(2) "19"
[1]=>
string(2) "13"
[2]=>
string(2) "15"
}
}
可以看出,第一个成员还是匹配的文本,但是个数组,每个成员都是被匹配到的文本;
而后面的数组数量取决于你设定了几个子表达式,就是用括号包起来的部分。
而每个数组中的每个值是按匹配到的文本数量进行排列,
也就是说,如果你要取出每个匹配文本中的两个温度,应该是用$match[1][i]
和$match[2][i]
(i
为要取出的第几个温度信息。)
有时候,我们想把匹配到的文本换成别的文本,比如把Copyright 20xx
换成Copyright 2019
,那就用preg_replace
。
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
$pattern
即匹配规则,$replacement
为替换规则,$subject
为需要匹配并替换的文本,$limit
为替换上限次数,$count
用来统计替换次数,一般用不到后两个参数,函数的返回值即替换结果。
实现下上述的操作吧:
$s = 'Copyright 2006,Copyright 2099,Copyright 2008,Copyright 2109';
$pat = '/Copyright 20../';
$rep = 'Copyright 2019';
echo preg_replace($pat, $rep, $s);
输出:Copyright 2019,Copyright 2019,Copyright 2019,Copyright 2109
参考资料:
[1] 正则表达式_百度百科
[2] PHP 正则表达式匹配函数 preg_match 与 preg_match_all