5.5 正则表达式语法规则
一般情况下,正则表达式由两部分组成,分别是元字符和文本字符。元字符就是具有特殊含义的字符,例如“? ”和“*”等,文本字符就是普通的文本,例如字母和数字等。本节主要讲述正则表达式的语法规则。
1.方括号([ ])
方括号内的一串字符是将要用来进行匹配的字符。例如,正则表达式在方括号内的[name]是指在目标字符串中寻找字母n、a、m、e。[jjk]表示在目标字符串中寻找字符j和k。
2.连字符(-)
在很多情况下,不可能逐个列出所有字符。比如,若要匹配所有英文字符,则把26个英文字母全部输入会十分困难。这样就有如下表示:
● [a-z]表示匹配英文小写从a到z的任意字符。
● [A-Z]表示匹配英文大写从A到Z的任意字符。
● [A-Za-z] 表示匹配英文大小写从大写A到小写z的任意字符。
● [0-9]表示匹配从0到9的任意十进制数。
由于字母和数字的区间固定,因此根据这样的表示方法,即[开始-结束],程序员可以重新定义区间大小,如[2-7]、[c-f]等。
3.点号字符(.)
点号字符在正则表达式中是一个通配符,代表所有字符和数字,例如,“.er”表示所有以er结尾的三个字符的字符串,可以是per、ser、ter、@er、&er等。
4.限定符(+*? {n, m})
● 加号“+”表示其前面的字符至少有一个。例如,“9+”表示目标字符串包含至少一个9。
● 星号“*”表示其前面的字符不止一个或零个。例如,“y*”表示目标字符串包含0或不止一个y。
● 问号“? ”表示其前面的字符为一个或零个。例如,“y? ”表示目标字符串包含0或一个y。
● 大括号“{n, m}”表示其前面的字符有n或m个。例如,“a{3,5}”表示目标字符串包含3个或5个a。“a{3}”表示目标字符串包含3个a。“a{3, }”表示目标字符串至少包含3个a。
点号和星号可以一起使用,如“.*”表示匹配任意字符。
5.行定位符(^和$)
行定位符用来确定匹配字符串所要出现的位置。
如果是在目标字符串开头出现,就使用符号“^”;如果是在目标字符串结尾出现,就使用符号“$”。例如,^xiaoming是指xiaoming只能出现在目标字符串开头,8895$ 是指8895只能出现在目标字符串结尾。
可以同时使用这两个符号,如“^[a-z]$”,表示目标字符串只包含从a到z的单个字符。
6.排除字符([^])
符号“^”在方括号内所代表的意义则完全不同,表示一个逻辑“否”,排除匹配字符串在目标字符串中出现的可能。例如,[^0-9]表示目标字符串包含从0到9“以外”的任意其他字符。
7.括号字符(( ))
括号字符表示子串,所有对包含在子串内字符的操作都是以子串为整体进行的。括号字符也是把正则表达式分成不同部分的操作符。
8.选择字符(|)
选择字符表示“或”选择。例如,“com|cn|com.cn|net”表示目标字符串包含com或cn或com.cn或net。
9.转义字符(\)与反斜线(\)
由于“\”在正则表达式中属于特殊字符,如果单独使用此字符,就直接表示为作为特殊字符的转义字符。如果要表示反斜杠字符本身,就在此字符前添加转义字符“\”,即“\\”。
10.认证email的正则表达
在处理表单数据的时候,对用户的email进行认证是十分常用的。可以使用正则表达式匹配来判断用户输入的是否为一个email地址。它的格式如下:
^[A-Za-z0-9_.]+@[ A-Za-z0-9_]+\.[ A-Za-z0-9.]+$
其中,^[A-Za-z0-9_.]+表示,至少有一个英文大小写字符、数字、下划线、点号,或者这些字符的组合。@表示email中的“@”。[ A-Za-z0-9_]+表示,至少有一个英文大小写字符、数字、下划线,或者这些字符的组合。\.表示email中“.com”之类的点。由于这里点号只是点本身,因此用反斜杠对它进行转义。[ A-Za-z0-9.]+$表示至少有一个英文大小写字符、数字、点号,或者这些字符的组合,并且直到这个字符串的末尾。
11.如何使用正则表达式对字符串进行匹配
使用正则表达式对目标字符串进行匹配是正则表达式的主要功能。
完成这个操作需要用到ereg()函数。这个函数用于在目标字符串中寻找符合特定正则表达规范的字符串子串,根据指定的模式来匹配文件名或字符串。其中,ereg()函数对字符大小写不敏感。它的语法格式如下:
ereg(正则表达规范,目标字符串,数组)
提示:另外用户也可以使用eregi()函数对字符串进行匹配,它和ereg()函数最大的区别是对字符大小写敏感。
下面介绍利用正则表达规范匹配email输入的方法和技巧。
【例5.12】(实例文件:ch05\5.12.php)
<? php $email = "wangxioaming2011@hotmail.com"; //定义字符串 $email2 = "The email is liuxiaoshuai_2011@hotmail.com"; $asemail = "This is wangxioaming2011@hotmail"; $regex = '^[a-zA-Z0-9_.]+@[a-zA-Z0-9_]+\.[a-zA-Z0-9.]+$'; //定义正则表达式规范 $regex2 = '[a-zA-Z0-9_.]+@[a-zA-Z0-9_]+\.[a-zA-Z0-9.]+$'; if(ereg($regex, $email, $a)){ //利用正则表达式规范字符串 echo "This is an email."; print_r($a); echo "<br />"; } if(ereg($regex2, $email2, $b)){ echo "This is a new email."; print_r($b); echo "<br />"; } if(ereg($regex, $asemail)){ echo "This is an email."; }else{ echo "This is not an email."; } ?>
运行结果如图5-12所示。
图5-12 程序运行结果
【案例分析】
(1)$email就是一个完整的email字符串,用$regex这个正则规范(匹配email的规范)来匹配$email,得出的结果为图中第一行输出。
(2)ereg($regex, $email, $a)把匹配的子串存储在名为$a的数组中。print_r($a)打印数组,得出结果为第一行数组输出。
(3)$email2是一个包含了完整email的字符串。用$regex匹配,其返回值必然为false。用$regex2规范匹配,其返回值为真。因为$regex2规范中去掉了表示从字符串头部开始的符号“^”。ereg($regex2, $email2, $b)把匹配的子串存储在数组$b中。print_r($b)得到第二行数组的输出。
(4)$asemail字符串不符合规范$regex,返回值为false,得到相应输出。
12.使用正则表达式替换字符串子串
完成字符串及其子串的匹配后,如果需要对字符串的子串进行替换,也可以使用正则表达式完成。例如,输入文本中的url变成可以直接单击的连接。此操作需要使用ereg_replace()和eregi_replace()函数。其中ereg_replace()对大小写敏感,而eregi_replace()对大小写不敏感。其格式为:
ereg_replace(正则表达规范,欲取代字符串子串,目标字符串)
提示
用户也可以使用eregi_replace ()函数对字符串进行替换。
通过以下实例介绍利用正则表达式取代字符串子串的方法和技巧。
【例5.13】(实例文件:ch05\5.13.php)
<? php $searchurl = "这是搜索引擎链接:http://www.google.com/和http://www.baidu.com/。"; echo ereg_replace("(http://)([a-zA-Z0-9./-_]+)", "<a href=\"\\0\">\\0</a>", $searchurl); echo "<br />"; echo ereg_replace("(http://)([a-zA-Z0-9./-_]+)", "<a href=\"\\0\">\\2</a>", $searchurl); ?>
运行结果如图5-13所示。
图5-13 程序运行结果
【案例分析】
(1)$searchurl里面包含两个url文本。ereg_replace()按照格式对$searchurl里的url进行匹配替换。
(2)正则规范为"(http://)([a-zA-Z0-9./-_]+)",可分为两部分,即(http://)和([a-zA-Z0-9./-_]+),前者直接匹配,后者用正则语法匹配。
(3)第一行的输出替换为"<a href=\"\\0\">\\0</a>"。里面的“\\0”把反斜杠转义后表示的是“\0”,“\0”表示正则规则中所有部分匹配的内容。第二行的输出替换为"<a href=\"\\0\">\\2</a>",里面的“\\2”把反斜杠转义后表示的是“\2”,“\2”表示正则规则中第二部分匹配的内容,输出如图5-13所示。依此类推,“\1”表示的是第一部分匹配的内容,即(http://)。
13.使用正则表达式切分字符串
使用正则表达式可以把目标字符串按照一定的正则规范切分成不同的子串。完成此操作要用到strtok()函数,它的语法格式为:
strtok(正则表达式规范,目标字符串)
这个函数以正则规范内出现的字符为准,把目标字符串切分成若干个子串,并且存入数组。
下面通过实例介绍利用正则表达式切分字符串的方法和技巧。
【例5.14】(实例文件:ch05\5.14.php)
<? php $string = "Hello world. Beautiful day today."; //定义字符串 $token = strtok($string, " "); //切分字符串 while ($token ! == false) //使用while循环输出切分后的字符串 { echo "$token<br />"; $token = strtok(" "); } ?>
运行结果如图5-14所示。
图5-14 程序运行结果
【案例分析】
(1)$string为包含多种字符的字符串。strtok($string, " ")对其进行切分,并将结果存入数组$token。
(2)正则规范为" ",以空格将字符串切分。