PHP 新手入门之正则表达式

1.定界符

什么是定界符?

所谓定界符,就是定一个边界,内容要写在这个边界内

//     这就是正则表达式中的定界符  表达式要写在//中间

即/a-z/

2.定界符有哪些?

除了字母、数字和反斜线以外的任何字符都可以为定界符号,比如 | |、//、{}、!!等等,但是需要注意,如果没有特殊需要,我们都应用作为正则表达式的定界符号

3.正则表达式的构成

一个标准的正则表达式由3部分构成:

(1).分隔符

(2).表达式

(3).修饰符

分隔符:分隔符用来包裹表达式,可以是除了特殊字符以外的任何字符,常用的分隔符“/”

表达式:表达式是由一些特殊字符(元字符)和非特殊字符(文本字符)组成

修饰符:在PHP正则表达式里面的修饰符可以改变正则的很多特性,使得正则表达式更加适合你的需要(注意:修饰符对于大小写是敏感的,这意味着"e"并不等于"E")

正则表达式中的修饰符有哪些呢?

PHP正则表达式修饰符的种类及介绍:

◆i :如果在修饰符中加上"i",则正则将会取消大小写敏感性,即"a"和"A" 是一样的。

◆m:默认的正则开始"^"和结束"$"只是对于正则字符串如果在修饰符中加上"m",那么开始和结束将会指字符串的每一行:每一行的开头就是"^",结尾就是"$"。

◆s:如果在修饰符中加入"s",那么默认的"."代表除了换行符以外的任何字符将会变成任意字符,也就是包括换行符!

◆x:如果加上该修饰符,表达式中的空白字符将会被忽略,除非它已经被转义。

◆e:本修饰符仅仅对于replacement有用,代表在replacement中作为PHP代码。

◆A:如果使用这个修饰符,那么表达式必须是匹配的字符串中的开头部分。比如说"/a/A"匹配"abcd"。

◆E:与"m"相反,如果使用这个修饰符,那么"$"将匹配绝对字符串的结尾,而不是换行符前面,默认就打开了这个模式。

◆U:和问号的作用差不多,用于设置"贪婪模式"。

正则表达式中的原子

原子是正则表达示里面的最小单位,原子说白了就是需要匹配的内容。一个成立的正则表达示当中必须最少要有一个原子

说明:我们见到的空格、回车、换行、0-9、A-Za-z、中文、标点符号、特殊符号全为原子。在做原子的实例前我们先来讲解一个函数,preg_match

语法:int preg_match ( string $正则 , string $字符串 [, array &$结果] )

上面是preg_match常用的主要几个参数。我在上面将另外几个参数没有列出来。因为,另外两个参数太不常用了。

我们来通过实验来证明:

<?php
	header("Content-type: text/html; charset=utf-8");//设置编码
	$zz = '/a/';

	$string = 'ddfdjjvai2jfvkwkfi24';

	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

注:$zz   为正则表达式的规则     $string 是一个字符串,本例是判断这个字符串是否满足匹配的正则表达式,如果满足,输出结果,不满足,输出信息

特殊标识的原子

图片1.png

d  匹配0-9

<?php
	header("Content-type: text/html; charset=utf-8");//设置编码

	//   \d的用法

	$zz = '/\d/';
	$string = '我爱喝9你爱不爱喝';

	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

D 除了0-9以外的所有字符

<?php
    //  \D   匹配出0-9以外的所有字符
	$zz = '/\D/';
	$string = '12124323453453';

	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

w   a-z A-Z0-9_

<?php 
	//  \w   匹配a-zA-Z0-9 还有下划线

	$zz = '/\w/';  
	$string = '新中_国万岁呀万岁';
	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

W   与w相反

<?php
    //\W  除a-zA-Z0-9_ 以外的所有字符

	$zz = '/\W/';  
	$string = '......';

	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

s  匹配所有的空白字符

<?php
        //  \s  匹配所有的空白字符
	$zz = '/\s/';
	$string = "中国万
	岁";

	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

S  非空字符

<?php
	//  \S  匹配非空字符
	$zz = '/\S/';
	$string = "        
          a       ";

	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

[] 指定范围的原子

<?php
	//  [] 指定原子范围
	$zz = '/[0-5]\w+/';
	$string = '6a';
	$string1 = '1C';
	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}

?>

大家看这些w  s  W  S  是有点记不住的,所以下面有等价的出来,效果是和s w 等等是一样的

图片2.png

+ 匹配最少1次前面的字符

<?php
	header("Content-type: text/html; charset=utf-8");//设置编码

	$zz = '/\d+/';

	$string = "迪奥和奥迪250都是我最爱";
	//待会儿再试试中间没有0-9的情况
	//$string = "迪奥和奥迪都是我最爱";

	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

*  匹配0次或者任意多次前面的字符

<?php
	$zz = '/\w*/';
	$string = "!@!@!!@#@!$@#!";
	//待会儿再试试中间没有0-9的情况
	//$string1 = "!@#!@#!abcABC#@#!";
	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

? 前面的字符出现0次或者1次,可有可无

<?php
    $zz = '/ABC\d?ABC/';
	$string = "ABC1ABC";
	//待会儿再试试中间没有0-9的情况
	//$string1 = "ABC888888ABC";
	//$string2 = "ABCABC";
	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

. (点) 匹配除n以外的所有字符

<?php
    
	$zz = '/gg.+gg/';
	$string = "ABC1ABC";
	if(preg_match($zz, $string, $matches)){
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	}else{
	    echo '没有匹配到';
	}
?>

|(竖线),或者,优先级最低

<?php
        $zz = '/abc|bcd/';
	$string1 = "abccd";
	$string2 = "ggggbcd";

	if (preg_match($zz, $string1, $matches)) {
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	} else {
	    echo '没有匹配到';
	}
?>

通过上面的实例我们看出:

1. 最开始我匹配的想法是想匹配的是abccd或者是abbcd。可是,匹配$string1和$string2,匹配出来的结果却是abc和bcd.

2. 实现了或者匹配,匹配出来了abc或者是bcd。它还没有字符串连续在一起的优先级高

^ (抑扬符),必须要以^之后的字符串开始

<?php
	$zz = '/^张杰好帅\w+/';
	$string1 = "张杰好帅abccdaaaasds";
	//$string2没有以张杰好帅开始
	$string2 = "帅abccdaaaasds";
	if (preg_match($zz, $string1, $matches)) {
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	} else {
	    echo '没有匹配到';
	}
?>

通过实验发现以下结论:

1. $string1匹配成功,$string2没有匹配成功

2. 因为$string1是以指定的字符开始的

3. 而$string2并没有以^之后的字符开始

4. 翻译这个正则的意思就是:以要李文凯好帅开始后面接a-zA-Z0-9_最少一个字符。

$ (美元符)必须要以$之前的字符结束

<?php
	$zz = '/\d+努力$/';
	$string1 = "12321124333努力";
	//$string2
	$string2 = "12311124112313力";

	if (preg_match($zz, $string1, $matches)) {
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	} else {
	    echo '没有匹配到';
	}
?>

注:

$string1 匹配成功,而$string2匹配不成功

$之前的字符是d+,后面接着中文的努力。

因此,匹配的是这一个整体。d指的是0-9的整型,+号代表最少一个0-9

{m}有且只能出现m次 

<?php
	$zz = '/喝\d{1,3}酒/';
	$string1 = "喝9酒";
	//$string2 = "喝988酒";
	if (preg_match($zz, $string1, $matches)) {
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	} else {
	    echo '没有匹配到';
	}
?>

注:上例中d{1,3}我规定了0-9只能出现1次,2次或者3次。其它次数都是错的

{m,} 至少m次,最大次数不限制

<?php
    	$zz = '/喝\d{2,}/';
	$string1 = "喝9";
	//$string2 = "喝98";
	//$string3 = "喝98122121";
	if (preg_match($zz, $string1, $matches)) {
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	} else {
	    echo '没有匹配到';
	}
?>

上例中d{2,}我规定喝后面的0-9最少出现两次,最多次数不限。因此$string1是匹配不成功的,$string2是匹配成功的。$string3是匹配成功的

正则表达式的技巧

写一点、测一点

因为,我们需要不断的正则,用preg_match对比是不是能匹配成功。成功了,再写后面的一点。直到写完,全部匹配成功为止!

接下来我们写个整合的例子  邮箱的正则表达式

第一步:把邮箱的格式全部列出来

liwenkai@phpxy.com

iwenkai@corp.baidu.cm

iwenkai@126.com

_w_k@xxx.com

2345@qq.com

先匹配@之前的字符 w+(因为是0-9A-Za-z_)

第二个跟一个@符

第三个再写上[a-zA-Z0-9-]+ 因为qq和126这些主域名是不能有下

划线的

corp.baidu. 或者是126. 通常邮箱后缀都是这样的。所以我们可以写成:([a-zA-Z0-9-]+.){1,2}

上面的是将.转义,让它是本身的意思。括号重复的区间最少一次,最多两次。

后面接下com|cn|org|gov.cn|net|edu.cn等就可以了

<?php
	header("Content-type: text/html; charset=utf-8");//设置编码

	$zz = '/\w+@([a-zA-Z0-9-]+.){1,2}(com|cn|org|gov.cn|net|edu.cn)/';

	$string1 = "k53981@qq.com";


	if (preg_match($zz, $string1, $matches)) {
	    echo '匹配到了,结果为:';
	    var_dump($matches);
	} else {
	    echo '没有匹配到';
	}

?>


继续学习
||
<?php header("Content-type: text/html; charset=utf-8");//设置编码 $zz = '/a/'; $string = 'ddfdjjvai2jfvkwkfi24'; if(preg_match($zz, $string, $matches)){ echo '匹配到了,结果为:'; var_dump($matches); }else{ echo '没有匹配到'; } ?>
提交重置代码