举一个简单的例子:在一个用户注册的页面中(例如,一个论坛或者交友网站的注册页面),上面可能有“电子邮件”这一项需要填写。对系统来说,需要判定用户所填写的电子邮件地址是否合法,即是否符合电子邮件地址的规则。利用字符串操作技术可以实现这个功能。
<!--检查电子邮件合法性:validate_email1.php-->
<?php
function validate_email1($email){
$hasAtSymbol = strpos($email, "@"); //检查是否包含@
//strpos($mystring, $findme);在$mystring中查找是否存在$findme,有则返回位置,否则返回false;
$hasDot = strpos($email, "."); //检查是否包含.
if($hasAtSymbol && $hasDot && $hasAtSymbol<$hasDot )
return 1;
else
return 0;
}
echo validate_email1("chen@sjolzy.cn"); //true
echo validate_email1(chen@sjolzy); //false
?>
上面代码实现了一个函数validate_email1(),使用字符串操作中的定位字符函数,判断一个字符串是否是一个合法的电子邮件地址的规则。仔细考虑实现的功能,实际上是在判断一个字符串是否具有一定的模式,或者说是否满足一定的规则。在这种情况下,可以使用正则表达式来实现相同的功能。
<!--使用正则表达式检查电子邮件合法性:validate_email2.php-->
<?php
function validate_email2($email){
return (int)ereg("^[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]+$", $email);
}
echo validate_email2(chen@sjolzy.cn); //true
echo validate_email2(chen@sjolzy); //false
?>
上面实现了具有相同功能的函数validate_email1(),函数使用了一个正则表达式的函数ereg() :以区分大小写的方式在 string 中寻找与给定的正则表达式 pattern 所匹配的子串。观察ereg()函数的参数“^[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]+$”,容易看出其实际上表示满足这样规则的字符串:以[a-zA-Z]即任意大小写字符串开头,然后紧跟“@”,然后又是任意大小写字母组成的字符串,第4部分是符号“.”,最后仍是任意字符串。这相当于定义了一个字符串的组成规则。
在看过这个示例后,重新来看正则表达式的定义:正则表达式是一种可以用于模式匹配的强大工具。
2 使用正则表达式
在PHP有6个函数来处理正则表达式,检查一个字符串是否满足一个的规则。它们都把一个正则表达式作为它们的第一个参数,语法如下。
bool ereg(string pattern, string string [, array regs]):最常用的正则表达式函数, 搜索跟正则表达式pattern匹配的一个字符串。区分大小写。搜索到返回true,否则返回false。
string ereg_replace(string pattern, string replacement, string string):搜索跟正则表达式pattern匹配的一个字符串,并用新的字符串代替所有这个表达式出现的地方。
bool eregi(string pattern, string string [, array regs]):搜索跟正则表达式pattern匹配的一个字符串。不区分大小写。搜索到返回true,否则返回false。
string eregi_replace(string pattern, string replacement, string string):和ereg_replace有着一样的搜索-替换功能,不过忽略大小写。
array split(string pattern, string string [, int limit]):搜索和正则表达式匹配的字符串,区分大小写并且以字符串集合的方式返回匹配结果。
array spliti(string pattern, string string [, int limit]):搜索和正则表达式匹配的字符串,不区分大小写,并且以字符串集合的方式返回匹配结果。
介绍了PHP的正则表达式函数及其功能。要了解它们的具体使用方法,则要首先了解正则表达式的构造。
3 构造正则表达式:
如前所述,在匹配一个字符串到正则表达式之前,必须先构造正则表达式。
1).定义头部规则
SPHP用“^”定义字符串头部的规则,例如:“^hello”即定义头部为“hello”的字符串,结合上一节所介绍的函数,代码<?php echo ereg("^hello", "hello world!"); ?> //true将返回“true”,因为待验证的字符串“hello word!”满足规则:以“hello”开头。而<?php echo ereg("^hello", "i say hello world"); ?> //false将返回 false,因为hello不在字符串”I say hello world”的头部。
2).定义尾部规则
<?PHP用“$”定义字符串尾的规则,例如:“world$”即定义尾部为“world”的字符串,代码
<?php echo ereg("world$", "hello world!"); ?> //true
将返回“true”,因为待验证的字符串“hello word!”满足规则:以“world”结尾。而
<?php echo ereg("world$", "i say hello php"); ?> //false
将返回 false,因为world不在字符串”I say hello php”的尾部。
3).定义包含任意字符规则$
PHP用“.”定义包含任意字符的规则,例如:“.”即定义包含任意字符的字符串,代码
<?php echo ereg(".", "something"); ?> //true
将返回“true”,因为待验证的字符串“something”满足规则:包含任意字符。而
<?php echo ereg(".", ""); ?> //false
将返回 false,因为空串不包含任意字符。
4).定义包含字符数目规则
使用大括号“{n}”定义包含n个任意字符,“{m,n}”定义包含m到n范围内的任意字符。
例如“.{3}”定义包含或超过3个连续任意字符的字符串,“.{1,3}”定义包含1到3个字符的字符串。代码
<?php echo ereg(".{3}", "abcd"); ?> //true
<?php echo ereg(".{1,3}", "aa"); ?> //true
都将返回“true”,因为待验证的字符串“aaa”满足规则:包含3个字符。而
<?php echo ereg(".{4}", "aaa"); ?> //false
将返回 false。
“.”也可以结合“^”和“$”使用,例如“.{3}$”定义了以3个字符结尾的字符串,“^.{3}”定义了以三个连续字符开头的字符串。代码
<?php echo ereg(".{3}$", "baaa"); ?> //true
将返回“true”,因为待验证的字符串“baaa”满足规则:以3个连续字符结尾。而
<?php echo ereg(".{3}$", "ab"); ?> //false
将返回 false。)
5).定义包含0~n个字符规则
PHP用“*”定义包含0~n个字符的规则,例如:“a*”即定义包含0~n个字符的字符串,代码
<?php echo ereg("a*", "aaa"); ?> //true
将返回“true”,因为待验证的字符串“aaa”满足规则:包含0~n个字符“a”。而
<?php echo ereg("a*", "bbb"); ?> //true
也将返回 true,因为待验证的字符串“bbb”也满足规则:包含0~n个字符“a”。
6).定义包含1~n个字符规则
PHP用“+”定义包含1~n个字符的规则,例如:“a+”即定义包含1~n个字符“a”的字符串,代码
<?php echo ereg("a+", "aaa"); ?> //true
将返回“true”,因为待验证的字符串“aaa”满足规则:包含1~n个字符“a”。而
<?php echo ereg("a+", "bbb"); ?> //false
将返回 false,因为待验证的字符串“bbb”不满足规则:包含1~n个字符“a”。
*7).定义包含0或1个字符规则
PHP用“?”定义包含0或1个字符的规则,例如:“a?”即定义包含0或1个字符“a”的字符串,代码
<?php echo ereg("a?", "a"); ?> //true
<?php echo ereg("a?", "bb"); ?> //true
将返回“true”,因为待验证的字符串“a”和“bb”都满足规则:包含0或1个字符“a”。而
<?php echo ereg("a?", "aa"); ?> //true
//(有错) 将返回false,因为待验证的字符串“bbb”不满足规则:包含0或1个字符“a”。
8).定义包含某范围的字符规则
PHP用方括号“[start-end]”定义包含start-end范围内任意字符的规则,例如:“[a-z]”即定义包含a到z范围内任意字符的字符串,代码
<?php echo ereg("^[a-z]+$", "abc"); ?> //true
将返回“true”,因为待验证的字符串“abc”满足规则:包含1~n个字符a~z范围内任意字符。
<?php echo ereg("^[a-z]+$", "ABC"); ?> //false
将返回 false,因为待验证的字符串“ABC”不满足规则:包含1~n个字符“a”。
9).定义包含某范围的词规则
PHP用圆括号“(word1|word2|…)”定义包含word1、word2、…的任意字符串的规则,例如:“(wang|zhang)”即定义包含“wang”或“zhang”的任意字符的字符串,代码
<?php echo ereg("^(wang|zhang)+$", "wang and zhang"); ?> //true
将返回“true”,因为待验证的字符串“wang and zhang”满足规则:以“wang”或“zhang”开头。
<?php echo ereg("^(wang|zhang)+$", "shi and jing"); ?> //false
将返回 false,因为待验证的字符串“shi and jing”不满足规则:以“wang”或“zhang”开头。
10).空格字符的处理
空格字符可以简单的处理为普通字符“ ”,但在实际使用中常用“[[:space]]”来代替,这样在字符串中更加易读。例如:“I[[:space]]am”表示为“I am”。
11).特殊字符的处理
因为一些字符要用在一个正则表达式语法上,像(wang|zhang)中的圆括号,需要屏蔽掉这些字符,使之成为字符串的一部分,而不是具有功能性的表达式的一部分。用转义字符,即反斜杠“\”可以实现这种转换,例如:
<?php echo ereg("^[a-zA-z]+\|[a-zA-z]+$", "wang|zhang"); ?>
在正则表达式中,需要转义的字符包括:^, $, (, ), ., [, |, *, ?, +, \ and {。
本节全面的介绍了如何构造一个正则表达式,即如何定义一个字符串组成规则。下一节,将给出一系列例子,通过例子,将进一步熟悉上述规则构造方法。
4 示例1验证
本小节实现利用PHP正则表达式验证URL合法性的示例。一个合法的URL如:
<a href="http://sjolzy.cn" target="_blank">sjolzy.cn</a>
其构造规则为:[协议]://[www].[域名].[com|net|org…]。
根据上一小节的构造正则表达式,可以构造下面的规则。
"^http://(www\ .)?.+\ .(com|net|org)$"
其中,"^http://”定义能匹配规则的字符串开头是"http://";"(www\ .)?"表示随后应该是0-1个“www”;而“.+”表示任意字符串;然后是一个“.”,转义字符“\”表明其仅仅是一个字符;最后的“(com|net|org)$”表明以com、net、org中其中一个结尾,此处,只列出这3种情况。完成验证URL合法性的函数如下所示。
<!--使用正则表达式检查URL合法性:validate_url.php-->
<?php
function isValidDomain($domainName)
{
return(int)ereg("^(http|ftp)://(www\.)?.+\.(com|net|org)$",$domainName);
}
echo isValidDomain(http://www.sjolzy.cn); //1
echo isValidDomain("http://sjolzy.com"); //1
echo isValidDomain("http://www.sjolzy.fr"); //0
echo isValidDomain("www.sjolzy.com"); //0
?>
5 示例2验证电话号码
本小节实现利用PHP正则表达式验证北京市电话号码合法性的的示例。合法的号码如:+86 010xxxxxxxx,其构造规则为:[+86] [010][八位数字]。
根据上一小节的构造正则表达式,可以构造下面的规则。
“^\+86[[:space:]]010[0-9]{8}$”
其中,“^\+86”定义能匹配规则的字符串开头是“+86”;“[[:space:]]”表示随后1个空格;而“[0-9]{8}$”表明以8个数字结尾。
完成验证北京市电话号码合法性的函数如下所示。
<!--使用正则表达式检查北京电话号码合法性:validate_phone.php-->
<?php
function isValidPhone($phoneNum)
{
echo (int)ereg("^\+86[[:space:]]010[0-9]{8}$", $phoneNum);
}
echo isValidPhone("+86 01012345678"); //1
echo isValidPhone("+86 010123456789"); //0
echo isValidPhone("+86 0101234567a"); //0
?>