PHP中相关正则表达式的函数
用正则表达式检查字符串是否是规定格式
在PHP中提供正则函数preg_match()来验证匹配,语法如下:
int preg_match ( string pattern, string subject [, array matches [, int flags]] )
该函数在subject字符串中搜索与pattern给出的正则表达式相匹配的内容。如果提供了matches,则其会被搜索的结果所填充。$matches[0] 将包含与整个模式匹配的文本, $matches[1]将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推。
preg_match()返回pattern所匹配的次数。是0次(没有匹配)或1次,因为preg_match()在第一次匹配之后将停止搜索。
(注意:PHP同样有提供ereg()函数来验证正则对字符串的匹配)
(TIPS: 如果只想查看一个字符串是否包含在另一个字符串中,虽然可以使用preg_match()来判断,但使用strpos()或string()替代会使判断速度更快)
假设要搜索一个包含字符"cat"的字符串,搜索用的正则表达式就是"cat"。如果搜索对大小不敏感,单词"catalog"、"Catherine"、"sophisticated"都可以匹配。下面是实现这个功能的一个例子。
<b>一个简单的正则表达式</b><hr /><p>
正则表达式:/cat/i
<?php
//模式定界符后面的"i"表示不区分大小写字母的搜索
if ( preg_match("/cat/i", "catalog") ) //使用preg_match与catalog进行匹配
{
echo "<p>catalog is matched.";
}
else
{
echo "<p>catalog is not matched.";
}
if ( preg_match("/cat/i/", "Catherine") )
{
echo "<p>Catherine is matched.";
}
else
{
echo "<p>Catherine is not matched.";
}
if ( preg_match("/cat/i", "sophisticated") )
{
echo "<p>sophisticated is matched.";
}
else
{
echo "<p>sophisticated is not matched.";
}
if (preg_match("/cat/i", "emmma") )
{
echo "<p>emmma is matched.";
}
else
{
echo"<p>emmma is not matched.";
}
?>
将字符串中特定的部分替换掉
preg_replace()函数实现查找字符串中某个特定的部分并替换成指定的字符
mixed preg_replace( mixed pattern, mixed replacement, mixed subject [, int limit] )
该函数在subject中搜索pattern模式的匹配项并替换为replacement。如果指定了limit,则仅替换limit个匹配,如果省略limit或者其值为-1,则所有的匹配项都会被替换。
replacement可以包含 \\n 形式或 $n 形式的逆向引用,首选使用后者。每个此种引用将被替换为与第n个被捕获的括号内的子模式所匹配的文本。n可以从0到99,其中 \\0 或 $0 指的是被整个模式所匹配的文本。对左圆括号从左到右技术(从1开始)以取得子模式的数目。
对替换模式在一个逆向引用后面 紧接着一个数字时(即:紧接着在一个匹配的模式后面的数字),不能使用熟悉的\\1符号来表示逆向引用。比如\\11,它将会使preg_replace()搞不清楚是想要一个\\1的逆向引用后面跟着一个数字1还是\\1的逆向引用。这个问题的解决方法是使用\${1}1。这会形成一个隔离的 $1逆向作用,而使另一个1知识单纯的数字
例子:
<b>将字符串中特定的部分替换掉</b><hr /><p>
<?php
$string = "我是福建人,我爱福建"; //原字符串
echo "<p>原字符串:" . $string; //输出原字符串
$pattern = "/福建/"; //查找的文字
$replacement = "河南";
echo "<p>替换后的字符串:";
echo preg_replace($pattern, $replacement, $string); //输出替换后的文字
?>
取得字符串中符合规定的部分
取得字符串中符合规定的部分也是一个常用的功能,此时需要用到preg_match_all()函数,语法如下:
int preg_match_all( string pattern, string subject, array matches [, int flags] )
该函数在subject中搜索所有与pattern给出的正则表达式匹配的内容并将结果以flags指定的顺序放到matches中。搜索到第一个匹配项之后,接下去的搜索从上一个匹配项末尾开始。matches会被搜索的结果所填充,
m
a
t
c
h
e
s
[
0
]
将
包
含
与
整
个
模
式
匹
配
的
文
本
,
matches[0]将包含与整个模式匹配的文本,
matches[0]将包含与整个模式匹配的文本,matches[1]将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推。
(注意:也可以使用前面提到的preg_match()函数取得字符串中规定的部分,但是它只能得到一次的匹配)
例子:
<b>取得页面中所有的链接地址</b><hr /><p>
<?php
$html = file_get_contents("https://www.baidu.com"); //取得页面的源代码
$html = mb_convert_encoding($html, "GBK", "UTF-8"); //进行转码操作
$a = "/<a[\s]+[^>]*href\=[\"']?([^>'\"]+)[\"']?[^>]*>/i"; //匹配链接地址的正则
preg_match_all($a, $html, $matches); //取得所有的匹配放入$matches
for($i=0; $i < count($matches[0]); $i++)
{
echo "<p>" . $matches[1][$i];
}
?>
在以上代码中,使用file_get_contents()函数来取得 一个网络上已有的页面。因为这个页面是"UTF-8"编码的,直接显示出来可能会出现乱码的情况,所以要再使用mb_convert_encoding()将它转成"GBK"码。之后需要重点注意的是匹配链接地址的正则"/<a[\s]+[>]*href=["’]?([>’"]+)["’]?[^>]*>/i".
解释如下:
/<a[\s]+[^>]*href\=[\"']?([^>'\"]+)[\"']?[^>]*>/i
|----------|(1)
|-------| |-----|(2)
|----------------------------------|
|-----------------|(4)
(1)所指示的正则表示匹配"<a" 与其后的一个以上空格,(2)表示匹配 所有不包含">"符号的字符,(3)表示匹配"herf="与其所跟的链接地址,(4)表示匹配的超级链接。运行后得到的结果如图:
常用的正则表达式
————注册用户时所需要用到的一些注册信息验证
检测邮件地址的真实性
<b>邮件地址的有效性</b><hr><p>
<?php
if($_GET['act'] == "validate")
{
/*使用preg_match函数配合电子邮件的正则进行验证*/
if(preg_match("/^[a-z0-9]+([_\.-]*[a-z0-9]+)*@[a-z0-9]([-]?[a-z0-9]+)\.[a-z]{2,3}(\.[a-z]{2})?$/i",$POST['email']))
{
echo "<font color='green'>此email有效!</font>"; //有效时的输出
}
else
{
echo "<font color='red'>此email无效!</font>"; //无效时的输出
}
die();
}
?>
<form action="?act=validate" method="post">
<input name="email" type="text">
<br /><br />
<input type="submit" value="验证">
</form>
以上代码首次运行时会显示一个提交表单,在输入框中输入需要验证的电子邮箱,如图所示。
这里对例子中使用的电子邮箱验证的正则做一个解释
^[a-z0-9]+([_\.-]*[a-z0-9]+)*@[a-z0-9]([-]?[a-z0-9]+)\.[a-z]{2,3}(\.[a-z]{2})?$
|-----------------------------------------------|(1)
|------------------------------------|(2)
|----------------|(3)
|-----------|(4)
(1)所指示的正则表示匹配“@“符号前的用户名。(2)表示”@“符号后第一个” . “符号前的域名,(3)表示匹配第一个” . "符号后的域名后缀,(4)匹配域名的第二个后缀
检查电话号码的真实性
<b>验证电话号码的有效性</b><hr><p>
<?php
if($_GET['act'] == "validate") //如果act为validate则开始验证
{
/*使用preg_match函数配合电话号码的正则进行验证*/
if(preg_match("/^[+]?[0-9]+([xX-][0-9]+)*$/i", $_POST['tel']))
{
echo "<font color='green'>此电话号码有效!</font>"; //有效时的输出
}
else
{
echo "<font color='red'>此电话号码无效!</font>"; //无效时输出
}
die(); //停止解析
}
?>
<form action="?act=validate" method="post">
<input name="tel" type="text">
<br /><br />
<input type="submit" value="验证">
</form>
首先对代码中的正则做一下解释,"[+]?[0-9]+“表示电话号码的区号,”[xX-]“表示区号与号码之间允许的分隔号,”[0-9]+"匹配的就是电话号码。
用户名的合法性检测
<b>验证用户名的有效性</b><hr><p>
<?php
if($_GET['act'] == "validate") //如果act为validate则开始验证
{
/*使用preg_match函数配合用户名的正则进行验证*/
if(preg_match("/^[_a-zA-Z0-9]*$/i", $_POST['name']))
{
echo "<font color='green'>此用户名有效!</font>"; //有效时的输出
}
else
{
echo "<font color='red'>此用户名无效!</font>"; //无效时的输出
}
die();
}
?>
<form action="?act=validate" method="post">
<input name="name" type="text">
<br /><br />
<input type="submit" value="验证">
</form>
使用正则表达式解释一下,"[_a-zA-Z0-9]*"表示含有字母,下划线和数字的任意个组合。
中文字符的检测
<b>验证 中文字符的有效性</b><hr><p>
<?php
if($_GET['act'] == "validate") //如果act为validate则开始验证
{
/*使用preg_match函数配合用户名的正则进行验证*/
// "/^[\x{4e00}-\x{9fa5}]+$/" 当编码为UTF-8时的正则
if( preg_match("/^[".chr(0xa1)."-".chr(0xff)."]+$/", $_POST['name']) )
{
echo "<font color='green'>此中文字符有效!</font>"; //有效时的输出
}
else
{
echo "<font color='red'>此中文字符无效!</font>"; //无效时的输出
}
die();
}
?>
<form action="?act=validate" method="post">
<input name="name" type="text">
<br /><br />
<input type="submit" value="验证">
</form>
其中的正则表达式的"chr(0xa1)"是汉字的起始内码,"chr(0xff)"是汉字的终止内码。这样就能容易地理解这个表达式匹配的是中文字符了。不过这个只能是应用在"GB2312"编码的字符串上。如果是"UTF-8"编码的就需要正则表达式 “/1+&/”
-
\x{4e00}-\x{9fa5} ↩︎