PHP 8从入门到精通(视频教学版)
上QQ阅读APP看书,第一时间看更新

5.6 正则表达式的语法规则

一般情况下,正则表达式由两部分组成,分别是元字符和文本字符。元字符就是具有特殊含义的字符,例如“?”和“*”等,文本字符就是普通的文本,例如字母和数字等。本节主要讲解正则表达式的语法规则。

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*”表示目标字符串包含零或不止一个y。

● 问号“?”:表示其前面的字符为一个或零个。例如,“y?”表示目标字符串包含零或一个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.如何使用正则表达式对字符串进行匹配

用正则表达式对目标字符串进行匹配是正则表达式的主要功能。

完成这个操作需要用到preg_match()函数。这个函数是在目标字符串中寻找符合特定正则表达式规范的字符串子串。根据指定的模式来匹配文件名或字符串。它的语法格式如下:

preg_match(正则表达式, 目标字符串,[ 数组])

下面介绍利用正则表达式规范匹配email输入的方法和技巧。

【例5.14】(实例文件:源文件\ch05\5.14.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(preg_match($regex, $email, $a)){                  //利用正则表达式规范字符串
    echo "This is an email.";
    print_r($a);
echo "<br/>";
}
if(preg_match($regex2, $email2, $b)){
    echo "This is a new email.";
    print_r($b);
    echo "<br/>";
}
if(preg_match ($regex, $asemail)){
    echo "This is an email.";
}else{
    echo "This is not an email.";
}
?>

运行结果如图5-14所示。

图5-14 程序运行结果

【案例分析】

(1)$email就是一个完整的email字符串,用$regex这个正则规范(匹配email的规范)来匹配$email,得出的结果为图5-14所示的第一行输出。

(2)preg_match ($regex, $email, $a)把匹配的子串存储在名为$a的数组中。print_r($a)打印数组,得出的结果为第一行数组输出。

(3)$email2是一个包含完整email的字符串。用$regex规范匹配,其返回值必然为false。用$regex2规范匹配,其返回值为ture。因为$regex2规范中去掉了表示从字符串头部开始的符号“^”。preg_match ($regex2, $email2, $b)把匹配的子串存储在数组$b中。print_r($b)得到第二行数组的输出。

(4)$asemail字符串不符合$regex规范,返回值为false,得到相应输出。

12.使用正则表达式替换字符串子串

做好了字符串及其子串的匹配,如果需要对字符串的子串进行替换,可以使用preg_replace()函数来完成。语法格式为:

preg_replace(正则表达式规范, 欲取代字符串子串, 目标字符串,[替换的个数])

如果省略替换的个数或者替换的个数为-1,则所有的匹配项都会被替换。

下面例子介绍利用正则表达式取代字符串子串的方法和技巧。

【例5.15】(实例文件:源文件\ch05\5.15.php)

<?php
$aa = "When you are old and grey and full of sleep";
$bb = "人生若只如初见,何事秋风悲画扇。人生若只如初见,何事秋风悲画扇。";
$aa= preg_replace('/\s/','-',$aa);
echo "第1次替换结果为:"."<br/>";
echo $aa."<br/>";
$bb= preg_replace('/何事/','往事',$bb);
echo "第2次替换结果为:"."<br/>";
echo $bb;
?>

运行结果如图5-15所示。

图5-15 使用正则表达式替换字符串的子串

【案例分析】

(1)第一次替换是将空格替换为'-',然后将替换后的结果输出。

(2)第二次替换是将'何事'替换为'往事',然后将替换后的结果输出。

13.使用正则表达式切分字符串

使用正则表达式可以把目标字符串按照一定的正则规范切分成不同的子串。完成此操作要用到strtok()函数,它的语法格式为:

strtok(正则表达式规范,目标字符串)

这个函数以正则规范内出现的字符为准,把目标字符串切分成若干个子串,并且存入数组。

下面通过实例介绍利用正则表达式切分字符串的方法和技巧。

【例5.16】(实例文件:源文件\ch05\5.16.php)

<?php
$string = "Hello world. Beautiful day today."; //定义字符串
$token = strtok($string, " ");                 //切分字符串
while ($token !== false)                       //使用while循环输出切分后的字符串
{
    echo "$token<br/>";
    $token = strtok(" ");
}
?>

运行结果如图5-16所示。

图5-16 程序运行结果

【案例分析】

(1)其中,$string为包含多种字符的字符串。strtok($string, " ")对其进行切分,并将结果存入数组$token。

(2)其正则规范为" ",表示以空格切分字符串。