本文實(shí)例講述了php正則表達(dá)式基本知識(shí)與應(yīng)用。分享給大家供大家參考,具體如下:
概述
正則表達(dá)式是一種描述字符串結(jié)果的語(yǔ)法規(guī)則,是一個(gè)特定的格式化模式,可以匹配、替換、截取匹配的字符串。常用的語(yǔ)言基本上都有正則表達(dá)式,如JavaScript、Java等。其實(shí),只有了解一種語(yǔ)言的正則使用,其他語(yǔ)言的正則使用起來(lái),就相對(duì)簡(jiǎn)單些。文本主要圍繞解決下面問(wèn)題展開(kāi)。
① 有哪些常用的轉(zhuǎn)義字符
② 什么是限定符與定位符
③ 什么是單詞定位符
④ 特殊字符有哪些
⑤ 什么是逆向引用以及怎樣使用逆向引用
⑥ 匹配模式
⑦ php中怎樣使用正則表達(dá)式
⑧ php中哪些方面需要用到正則
⑨ 怎樣進(jìn)行郵箱匹配,url匹配,手機(jī)匹配
⑩ 怎樣使用正則替換字符串中某些字符
⑪ 貪婪匹配與惰性匹配區(qū)別
⑫ 正則表達(dá)式之回溯與固態(tài)分組
⑬ 正則優(yōu)缺點(diǎn)有哪些
正則表達(dá)式的基本知識(shí)匯總
行定位符(^與$)
行定位符是用來(lái)描述字符串的邊界。“$”表示行結(jié)尾“^”表示行開(kāi)始如"^de",表示以de開(kāi)頭的字符串 "de$",表示以de結(jié)尾的字符串。
單詞定界符
我們?cè)诓檎业囊粋€(gè)單詞的時(shí)候,如an是否在一個(gè)字符串”gril and body”中存在,很明顯如果匹配的話,an肯定是可以匹配字符串“gril and body”匹配到,怎樣才能讓其匹配單詞,而不是單詞的一部分呢?這時(shí)候,我們可以是喲個(gè)單詞定界符b。
banb 去匹配”gril and body”的話,就會(huì)提示匹配不到。
當(dāng)然還有一個(gè)大寫(xiě)的B,它的意思,和b正好相反,它匹配的字符串不能使一個(gè)完整的單詞,而是其他單詞或字符串中的一部分。如BanB。
選擇字符(|) ,表示或
選擇字符表示或的意思。如Aa|aA,表示Aa或者是aA的意思。注意使用”[]”與”|”的區(qū)別,在于”[]”只能匹配單個(gè)字符,而”|”可以匹配任意長(zhǎng)度的字符串。在使用”[]”的時(shí)候,往往配合連接字符”-“一起使用,如[a-d],代表a或b或c或d。
排除字符,排除操作
正則表達(dá)式提供了”^”來(lái)表示排除不符合的字符,^一般放在[]中。如[^1-5],該字符不是1~5之間的數(shù)字。
限定符(?*+{n,m})
限定符主要是用來(lái)限定每個(gè)字符串出現(xiàn)的次數(shù)。
限定字符
含義
?
零次或一次
*
零次或多次
+
一次或多次
{n}
n次
{n,}
至少n次
{n,m}
n到m次
如(D+)表示一個(gè)或多個(gè)D
點(diǎn)號(hào)操作符
匹配任意一個(gè)字符(不包含換行符)
表達(dá)式中的反斜杠()
表達(dá)式中的反斜杠有多重意義,如轉(zhuǎn)義、指定預(yù)定義的字符集、定義斷言、顯示不打印的字符。
轉(zhuǎn)義字符
轉(zhuǎn)義字符主要是將一些特殊字符轉(zhuǎn)為普通字符。而這些常用特殊字符有”.”,”?”、””等。
指定預(yù)定義的字符集
字符
含義
d
任意一個(gè)十進(jìn)制數(shù)字[0-9]
D
任意一個(gè)非十進(jìn)制數(shù)字
s
任意一個(gè)空白字符(空格、換行符、換頁(yè)符、回車(chē)符、字表符)
S
任意一個(gè)非空白字符
w
任意一個(gè)單詞字符
W
任意個(gè)非單詞字符
###顯示不可打印的字符
字符
含義
a
報(bào)警
b
退格
f
換頁(yè)
n
換行
r
回車(chē)
t
字表符
括號(hào)字符()
在正則表達(dá)式中小括號(hào)的作用主要有:
改變限定符如(|、* 、^)的作用范圍
如(my|your)baby,如果沒(méi)有”()”,|將匹配的是要么是my,要么是yourbaby,有了小括號(hào),匹配的就是mybaby或yourbaby。
進(jìn)行分組,便于反向引用
反向引用
反向引用,就是依靠子表達(dá)式的”記憶”功能,匹配連續(xù)出現(xiàn)的字串或是字符。如(dqs)(pps)12,表示匹配字符串dqsppsdqspps。在下面php應(yīng)用中,我將詳細(xì)展開(kāi)學(xué)習(xí)反向引用。
模式修飾符
模式修飾符的作用是設(shè)定模式,也就是正則表達(dá)式如何解釋。php中主要模式如下表:
修飾符
說(shuō)明
i
忽略大小寫(xiě)
m
多文本模式
s
單行文本模式
x
忽略空白字符
正則表達(dá)式在php中應(yīng)用
php中字符串匹配
所謂的字符串匹配,言外之意就是判斷一個(gè)字符串中,是否包含或是等于另一個(gè)字符串。如果不使用正則,我們可以使用php中提供了很多方法進(jìn)行這樣的判斷。
不使用正則匹配
strstr函數(shù)
string strstr ( string haystack,mixedneedle [, bool $before_needle = false ])
注1:haystack是當(dāng)事字符串,needle是被查找的字符串。該函數(shù)區(qū)分大小寫(xiě)。
注2:返回值是從needle開(kāi)始到最后。
注3:關(guān)于$needle,如果不是字符串,被當(dāng)作整形來(lái)作為字符的序號(hào)來(lái)使用。
注4:before_needle若為true,則返回前東西。
stristr函數(shù)與strstr函數(shù)相同,只是它不區(qū)分大小寫(xiě)
strpo函數(shù)
int strpos ( string haystack,mixedneedle [, int $offset = 0 ] )
注1:可選的 offset 參數(shù)可以用來(lái)指定從 haystack 中的哪一個(gè)字符開(kāi)始查找。返回的數(shù)字位置是相對(duì)于 haystack 的起始位置而言的。
stripos -查找字符串首次出現(xiàn)的位置(不區(qū)分大小定)
strrpos -計(jì)算指定字符串在目標(biāo)字符串中最后一次出現(xiàn)的位置
strripos -計(jì)算指定字符串在目標(biāo)字符串中最后一次出現(xiàn)的位置(不區(qū)分大小寫(xiě))
使用正則進(jìn)行匹配
在php中,提供了preg_math()和preg_match_all函數(shù)進(jìn)行正則匹配。關(guān)于這兩個(gè)函數(shù)原型如下:
int preg_match|preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
搜索subject與pattern給定的正則表達(dá)式的一個(gè)匹配.
pattern:要搜索的模式,字符串類(lèi)型。
subject :輸入字符串。
matches:如果提供了參數(shù)matches,它將被填充為搜索結(jié)果。 matches[0]將包含完整模式匹配到的文本,matches[1]將包含第一個(gè)捕獲子組匹配到的文本,以此類(lèi)推。
flags:flags可以被設(shè)置為以下標(biāo)記值:PREG_OFFSET_CAPTURE 如果傳遞了這個(gè)標(biāo)記,對(duì)于每一個(gè)出現(xiàn)的匹配返回時(shí)會(huì)附加字符串偏移量(相對(duì)于目標(biāo)字符串的)。 注意:這會(huì)改變填充到matches參數(shù)的數(shù)組,使其每個(gè)元素成為一個(gè)由 第0個(gè)元素是匹配到的字符串,第1個(gè)元素是該匹配字符串 在目標(biāo)字符串subject中的偏移量。
offset:通常,搜索從目標(biāo)字符串的開(kāi)始位置開(kāi)始。可選參數(shù) offset 用于 指定從目標(biāo)字符串的某個(gè)未知開(kāi)始搜索(單位是字節(jié))。
返回值:preg_match()返回 pattern 的匹配次數(shù)。 它的值將是0次(不匹配)或1次,因?yàn)?preg_match()在第一次匹配后 將會(huì)停止搜索。 preg_match_all()不同于此,它會(huì)一直搜索subject直到到達(dá)結(jié)尾。 如果發(fā)生錯(cuò)誤 preg_match()返回 FALSE。
實(shí)例
實(shí)例1
判斷字符串”http://blog.csdn.net/hsd2012“中是否包含csdn?
解法一(不使用正則):
如果不適用正則,我們使用strstr或者strpos中任意一個(gè)都可以,在此,我將使用strstr函數(shù),代碼如下:
$str='http://blog.csdn.net/hsd2012'; function checkStr1($str,$str2) { return strstr1($str,$str2)?true:false; } echo checkStr($str,'csdn');
解法二:使用正則
因?yàn)槲覀冎恍枰袛嗍欠翊嬖诩纯桑赃x擇preg_match。
$str='http://blog.csdn.net/hsd2012'; $pattern='/csdn/'; function checkStr2($str,$str2) { return preg_match($str2,$str)?true:false; } echo checkStr2($str,$pattern);
實(shí)例2(考察單詞定界符)
判斷字符串”I am a good boy”中是否包含單詞go
首先判斷是單詞,而不是字符串,因此比較的時(shí)候,需要比較是否包含' go ‘,即在字符串go前后有一個(gè)空格。
解析:如果使用非正則比較,只需要調(diào)用上面的checkStr1()函數(shù)即可,注意,第二個(gè)參數(shù)前后要加一個(gè)空格,即' go ‘。如果使用正則,
我們可以考慮使用單詞定界符b,那么$pattern='/bgob/';然后調(diào)用checkStr2函數(shù)即可.
例3(考察反向引用)
判斷字符串”I am a good boy”中是否包含3個(gè)相同的字母
解析:此時(shí),如果我們不使用正則,將會(huì)很難判斷,因?yàn)樽帜柑嗔耍覀儾豢赡苋⑺凶帜阜謩e與該字符串比較,那樣工作量也比較大。這時(shí)候涉及到了正在的反向引用。在php正則表達(dá)式中,通過(guò)n,來(lái)表示第n次匹配到的結(jié)果。如5代表第五次匹配到的結(jié)果。那么本題的$pattern='/(w).*1.*1/';
主要注意的是,在使用反向匹配的時(shí)候都需要使用(),反向匹配時(shí),匹配()里面出現(xiàn)的字符或字符串。
php中字符串替換
不使用正則
php中當(dāng)替換字符串的時(shí)候,如果不適用正則,我們通常使用substr、mb_substr、str_replace、substr_replace關(guān)于這幾個(gè)函數(shù)區(qū)別如下表。
函數(shù)符
功能
描述
str_replace(find,replace,string,count)
使用一個(gè)字符串替換字符串中的另一些字符。
find 必需。規(guī)定要查找的值。replace 必需。規(guī)定替換 find 中的值的值。string 必需。規(guī)定被搜索的字符串。count 可選。一個(gè)變量,對(duì)替換數(shù)進(jìn)行計(jì)數(shù)。
substr_replace(string,replacement,start,length)
把字符串的一部分替換為另一個(gè)字符串。適合用于替換自定位置的字符串。
string 必需。規(guī)定要檢查的字符串。replacement 必需。規(guī)定要插入的字符串。start 必需。規(guī)定在字符串的何處開(kāi)始替換。
使用正則
如果使用正則替換,php中提供了preg_replace _callback和preg_replace 函數(shù),preg_replace 原型如下:
mixed preg_replace ( mixed pattern,mixedreplacement , mixed subject[,intlimit = -1 [, int &count]])
函數(shù)功能描述:在字符串subject中,查找pattern,然后使用replacement 去替換,如果有l(wèi)imit則代表限制替換limit次。pregreplacecallback與pregreplace功能相識(shí),不同的是pregreplaceback使用一個(gè)回調(diào)函數(shù)callback來(lái)代替replacement.−例1將字符串”hello,中國(guó)”中的hello替換為′你好′;如果不是用正則:str='hello,中國(guó)';
str=strreplace(′hello′,′你好′,str)
或是使用
str=substrreplace(str,'你好',0,5)
使用正則
pattern=′/hello/′;str=preg_replace (pattern,′你好′,str);
- 例2
去除字符串”gawwenngeeojjgegop”中連續(xù)相同的字母
$str='gawwenngeeojjgegop'; $pattern='/(.)1/'; $str=preg_replace($pattern,'',$str);
解析:當(dāng)然這樣可能會(huì)遇到,當(dāng)?shù)谝淮稳コ酥貜?fù)了字符串后,又出來(lái)重復(fù)的字符串。如字符串味'gewwenngeeojjgegop',針對(duì)這中問(wèn)題,當(dāng)然,這樣的話,通過(guò)判斷,繼續(xù)替換下去。
例3
將字符串中”age13gegep3iorji65k65k”;中出現(xiàn)的連續(xù)兩個(gè)數(shù)字改為第二個(gè)數(shù)字,如字符串中13被改為3
$str='age13gegep3iorji65k65k'; $pattern='/(d)(d)/'; $str=preg_replace($pattern,'$2', $str);
解析:$n在正則表達(dá)式外使用反向引用。n代表第幾次匹配到的結(jié)果。
php中字符串分割
不使用正則
php提供了explode函數(shù)去分割字符串,與其對(duì)應(yīng)的是implode。關(guān)于explode原型如下:
array explode ( string delimiter,stringstring [, int $limit ] )
delimiter:邊界上的分隔字符。
string:輸入的字符串。
limit:如果設(shè)置了 limit 參數(shù)并且是正數(shù),則返回的數(shù)組包含最多 limit 個(gè)元素,而最后那個(gè)元素將包含 string 的剩余部分。如果 limit 參數(shù)是負(fù)數(shù),則返回除了最后的 -limit 個(gè)元素外的所有元素。如果 limit 是 0,則會(huì)被當(dāng)做 1。
使用正則
關(guān)于通過(guò)正則表達(dá)式進(jìn)行字符串分割,php提供了split、preg_split 函數(shù)。preg_split() 函數(shù),通常是比 split() 更快的替代方案。
array preg_split ( string pattern,stringsubject [, int limit=−1[,intflags = 0 ]] )
例題
將字符串 ‘http://blog.csdn.net/hsd2012/article/details/51152810‘按照'/'進(jìn)行分割
解法一:
$str='http://blog.csdn.net/hsd2012/article/details/51152810'; $str=explode('/', $str);
解法二:
$str='http://blog.csdn.net/hsd2012/article/details/51152810'; $pattern='///'; /*因?yàn)?為特殊字符,需要轉(zhuǎn)移*/ $str=preg_split ($pattern, $str);
php中貪婪匹配與惰性匹配
貪婪匹配:就是匹配盡可能多的字符。
比如,正則表達(dá)式中m.*n,它將匹配最長(zhǎng)以m開(kāi)始,n結(jié)尾的字符串。如果用它來(lái)搜索manmpndegenc的話,它將匹配到的字符串是manmpndegen而非man。可以這樣想,當(dāng)匹配到m的時(shí)候,它將從后面往前匹配字符n。
懶惰匹配:就是匹配盡可能少的字符。
有的時(shí)候,我們需要并不是去貪婪匹配,而是盡可能少的去匹配。這時(shí)候,就需要將其轉(zhuǎn)為惰性匹配。怎樣將一個(gè)貪婪匹配轉(zhuǎn)為惰性匹配呢?只需要在其后面添加一個(gè)”?”即可。如m.*?n將匹配manmpndegenc,匹配到的字符串是man。
函數(shù)符
描述
*?
零次或多次,但盡可能少的匹配
+?
一次或多次,但盡可能少的匹配
??
0次或1次,但盡可能少的匹配
{n,}?
至少n次,但盡可能少的匹配
{n,m}?
n到m次 ,但盡可能少的匹配
php正則表達(dá)式之回溯與固態(tài)分組
回溯
首先我們需要清楚什么是回溯,回溯就像是在走岔路口,當(dāng)遇到岔路的時(shí)候就先在每個(gè)路口做一個(gè)標(biāo)記。如果走了死路,就可以照原路返回,直到遇見(jiàn)之前所做過(guò)的標(biāo)記,標(biāo)記著還未嘗試過(guò)的道路。如果那條路也走不能,可以繼續(xù)返回,找到下一個(gè)標(biāo)記,如此重復(fù),直到找到出路,或者直到完成所有沒(méi)有嘗試過(guò)的路。首先我們看例題
$str='aageacwgewcaw'; $pattern='/aw*c/i'; $str=preg_match($pattern, $str);
看到上面的程序,可能都清楚是什么意思,就是匹配$str是否包含這樣一個(gè)由”a+0個(gè)或多個(gè)字母+c”不區(qū)分大小寫(xiě)的字符串。但是至于程序怎樣去匹配的呢?匹配的過(guò)程中,回溯了多少次呢?
匹配過(guò)程
接下來(lái)操作描述
‘a(chǎn)w*c'中a匹配到'aageacwgewcaw'中第一個(gè)字符a
w進(jìn)行下一個(gè)字符匹配
因?yàn)閣是貪婪匹配,會(huì)一直匹配到'aageacwgewcaw'中最后一個(gè)字符w
c進(jìn)行下一個(gè)字符匹配時(shí)
‘a(chǎn)w*c'中c發(fā)現(xiàn)沒(méi)有可以匹配的
于是w匹配進(jìn)行第一次回溯,匹配到倒數(shù)第二個(gè)字符a
‘a(chǎn)w*c'中c發(fā)現(xiàn)還是沒(méi)有可以匹配的
于是w匹配進(jìn)行第二次回溯,匹配到倒數(shù)第三個(gè)字符c
‘a(chǎn)w*c'中c匹配成功
匹配結(jié)束返回結(jié)果
現(xiàn)在,如果我們將pattern改為pattern='/aw*?c/i';又會(huì)回溯多少次呢?正確答案是回溯四次。
固態(tài)分組
固態(tài)分組,目的就是減少回溯次數(shù), 使用(?>…)括號(hào)中的匹配時(shí)如果產(chǎn)生了備選狀態(tài),那么一旦離開(kāi)括號(hào)便會(huì)被立即 引擎拋棄掉。舉個(gè)典型的例子如: ‘w+:'這個(gè)表達(dá)式在進(jìn)行匹配時(shí)的流程是這樣的,會(huì)優(yōu)先去匹配所有的符合w的字符,假如字符串的末尾沒(méi)有':',即匹配沒(méi)有找到冒號(hào),此時(shí)觸發(fā)回溯機(jī)制,他會(huì)迫使前面的w+釋放字符,并且在交還的字符中重新嘗試與':'作比對(duì)。但是問(wèn)題出現(xiàn)在這里: w是不包含冒號(hào)的,顯然無(wú)論如何都不會(huì)匹配成功,可是依照回溯機(jī)制,引擎還是得硬著頭皮往前找,這就是對(duì)資源的浪費(fèi)。所以我們就需要避免這種回溯,對(duì)此的方法就是將前面匹配到的內(nèi)容固化,不令其存儲(chǔ)備用狀態(tài)!,那么引擎就會(huì)因?yàn)闆](méi)有備用狀態(tài)可用而只得結(jié)束匹配過(guò)程。大大減少回溯的次數(shù)。
如下代碼,就不會(huì)進(jìn)行回溯:
$str='nihaoaheloo'; $pattern='/(?>w+):/'; $rs=preg_match($pattern, $str);
當(dāng)然有的時(shí)候,又需慎用固態(tài)分組,如下,我要檢查$str中是否包含以a結(jié)尾的字符串,很明顯是包含的,但是因?yàn)槭褂昧斯虘B(tài)分組,反而達(dá)不到我們想要的效果
$str='nihaoahelaa'; $pattern1='/(?>w+)a/'; $pattern2='/w+a/'; $rs=preg_match($pattern1, $str);//0 $rs=preg_match($pattern2, $str);//1
php中其他常用字符串操作函數(shù)
字符串截取截取
string substr ( string string,intstart [, int length])stringmbsubstr(stringstr , int start[,intlength = NULL [, string $encoding = mb_internal_encoding() ]] )
字符串中大小寫(xiě)轉(zhuǎn)換
strtoupper
strtolower
ucfirst
ucwords
字符串比較
-strcmp、strcasecmp、strnatcmp
字符串過(guò)濾
字符串翻轉(zhuǎn)
strrev($str);
字符串隨機(jī)排序
string str_shuffle ( string $str )
補(bǔ)充
怎樣進(jìn)行郵箱匹配,url匹配,手機(jī)匹配
使用preg_match函數(shù)進(jìn)行匹配,以下內(nèi)容從TP中復(fù)制而來(lái)。
郵箱驗(yàn)證
pattern=′/w+([−+.]w+)∗@w+([−.]w+)∗.w+([−.]w+)∗/';
url匹配
pattern='/^http(s?)://(?:[A-za-z0-9-]+.)+[A-za-z]{2,4}(:d+)?(?:[/?#][/=?%-&~`@[]':+!.#w]*)?/';
手機(jī)驗(yàn)證
pattern=′/1[3458]d10/';
php中正則的優(yōu)缺點(diǎn)
php中正則在某些時(shí)候,能幫我們解決php函數(shù)很多困難的匹配或是替換。然后php中正則的效率,往往是我們需要考慮的,所以在某些時(shí)候,能不用正則還是盡量不去用它,除非,某些場(chǎng)合必須用到,或是我們能夠有效減少其回溯次數(shù)。
PS:這里再為大家提供2款非常方便的正則表達(dá)式工具供大家參考使用:
JavaScript正則表達(dá)式在線測(cè)試工具:
http://tools.gimoo.net/regex/javascript
正則表達(dá)式在線生成工具:
http://tools.gimoo.net/regex/create_reg
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《php正則表達(dá)式用法總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語(yǔ)法入門(mén)教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《PHP網(wǎng)絡(luò)編程技巧總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。