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相反

##\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 '没有匹配到';
	}

?>

图片2.png

大家看這些\w  \s \W  \S  是有點記不住的,所以下面有等價的出來,效果是和\s \w 等等是一樣的

+ 匹配最少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 '没有匹配到'; } ?>