首頁  >  文章  >  後端開發  >  PHP 中的正規關係

PHP 中的正規關係

不言
不言原創
2018-04-23 13:55:081528瀏覽

這篇文章介紹的內容是關於PHP 中的正規關係,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

概述

正規表示式是一種描述字串結果的語法規則,是一個特定的格式化模式,可以匹配、替換、截取匹配的字串。常用的語言基本上都有正規表示式,如JavaScript、java等。其實,只有了解一種語言的正規使用,其他語言的正則使用起來,就相對簡單些。文本主要圍繞著解決下面問題。

  • 有哪些常用的轉義字元

  • 什麼是限定符與定位符號

  • 什麼是單字定位符

  • 特殊字元有哪些

  • 什麼是逆向引用以及怎樣使用逆向引用

  • 匹配模式

  • php中怎樣使用正規表示式

  • php中哪些方面需要用到正規

  • 怎麼進行郵箱匹配,url匹配,手機匹配

  • 怎麼使用正則替換字符串中某些字符

  • 貪婪匹配與惰性匹配區別

  • 正規表示式之回溯與固態分組

  • 正則優缺點有哪些

正規表示式的基本知識總和

行定位符(^與$)

行定位符是用來描述字串的邊界。 “$”表示行結尾“^”表示行開始如"^de",表示以de開頭的字串 "de$" ,表示以de結尾的字串。

單字定界符

我們在尋找的一個單字的時候,如an是否在一個字串”gril and body」中存在,很明顯如果匹配的話,an肯定是可以匹配字串“gril and body”匹配到,怎樣才能讓其匹配單詞,而不是單字的一部分?這時候,我們可以是喲個單字定界符\b。 
\ban\b 去配對」gril and body」的話,就會提示配對不到。 
當然還有一個大寫的\B,它的意思,和\b正好相反,它匹配的字串不能使一個完整的單詞,而是其他單字或字串中的一部分。如\Ban\B。

選擇字元(|) ,表示或

選擇字元表示或的意思。如Aa|aA,表示Aa或aA的意思。注意使用”[]”與”|”的區別,在於”[]”只能匹配單個字符,而”|”可以匹配任意長度的字符串。在使用”[]”的時候,往往配合連接字符”-“一起使用,如[a-d],代表a或b或c或d。

排除字符,排除操作

正則表達式提供了”^”來表示排除不符合的字符,^一般放在[]中。如[^1-5],該字元不是1~5之間的數字。

限定符(?* {n,m})

限定符主要是用來限定每個字串出現的次數。

限定字元 意思
零次或一次
* 零次或多次
#一次或多次
{n} n次
#{n,} #至少n次
{n,m} n到m次
##如(D )表示一個或多個D

點號運算子

符合任何一個字元(不包含換行符)

表達式中的反斜線(

\)

表達式中的反斜線有多重意義,如轉義、指定預先定義的字元集、定義斷言、顯示不列印的字元。

轉義字元

轉義字元主要是將一些特殊字元轉為普通字元。而這些常用特殊字元有”.”,”?”、”\”等。

指定預先定義的字元集

字元##\d#\D
任一個十進位數字[0-9]
任一個非十進位數字
##\s 任一個空白字元(空格、換行符號、換頁符號、回車符、字表符)
\S 任一個非空白字元
\w

任一個單字字元##意義\a警報\b退格\f換頁#\n換行
\W 任意非單字字元
顯示無法列印的字元
###\r######Enter############\t######字表符########### #

括號字元()

在正規表示式中小括號的作用主要有:

  • 改變限定符如(|、* 、^)的作用範圍
    如(my|your)baby,如果沒有”()”,|將匹配的是要么是my,要么是yourbaby,有了小括號,匹配的就是mybaby或yourbaby。

  • 進行分組,便於反向引用

反向引用

反向引用,就是依賴子表達式的”記憶”功能,匹配連續出現的字符串或是字符。如(dqs)(pps)\1\2,表示符合字串dqsppsdqspps。在下面ph​​p應用中,我將詳細展開學習反向引用。

模式修飾符

模式修飾符的作用是設定模式,也就是正規表示式如何解釋。 php中主要模式如下表:

##i 忽略大小寫m多重文字模式##sx

正規表示式在php中應用

php中字串匹配

所謂的字串匹配,言外之意就是判斷一個字串中,是否包含或是等於另一個字串。如果不使用正規則,我們可以使用php中提供了很多方法來進行這樣的判斷。

不使用正規比對

  • strstr函數 
    string strstr ( string # aystack,mi
    x
    e
    dneedle [, bool $before_needle = false ]) 

    • ##haystack#當#字字串#,needle是被尋找的字串。此函數區分大小寫。


  • 註2:傳回值是從needle開始到最後。 註3:關於$needle,如果不是字串,被當作整形來當作字元的序號來使用。 註4:before_needle若為true,則回傳前東西。
    stristr函數與strstr函數相同,只是它不區分大小寫
    strpo函數 
    int strpos ( string 
    h
    a
    y
    s
    t

    a
  • c
  • k

    ,mixe

    dneedle [, int $offset = 0 ] ) 
  • 註1:可選的offset 參數可以用來指定從haystack 中的哪一個字元開始查找。傳回的數位位置是相對於 haystack 的起始位置而言的。

## #############stripos -尋找字串###首次出現###的位置(###不區分大小###定)########### ##strrpos -計算指定字串在目標字串中###最後一次出現###的位置#############strripos -計算指定字串在目標字串中###最後一次出現###的位置(###不區分大小寫###)#############使用正規進行比對######在php中,提供了preg_math( )和preg_match_all函數進行正規比對。關於這兩個函數原型如下:###
int preg_match|preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )

搜尋subject與pattern給定的正規表示式的一個符合. 
pattern:要搜尋的模式,字串型別。 
subject :輸入字串。 
matches:如果提供了參數matches,它將被填入搜尋結果。 matches[0]# 整#模#到

文字
#,matches[1]將包含第一個捕獲子組匹配到的文本,以此類推。 
flags:flags可以被設定為以下標記值:PREG_OFFSET_CAPTURE 如果傳遞了這個標記,對於每一個出現的匹配返回時會附加字串偏移量(相對於目標字串的)。注意:這會改變填充到matches參數的數組,使其每個元素成為由第0個元素是匹配到的字串,第1個元素是該匹配字串在目標字串subject中的偏移量。 
offset:通常,搜尋從目標字串的起始位置開始。可選參數 offset 用於 指​​定從目標字串的某個未知開始搜尋(單位是位元組)。 
傳回值:preg_match()傳回 pattern 的符合次數。它的值將是0次(不匹配)或1次,因為 preg_match()在第一次匹配後 將會停止搜尋。 preg_match_all()不同於此,它會一直搜尋subject直到到達結尾。如果發生錯誤 preg_match()回傳 FALSE。





  • 實例


    #實例1 
    判斷字串」http://blog.csdn .net/hsd2012「中是否包含csdn? 

    解法一(不適用正規): 
  • 如果不適用正規則,我們使用strstr或strpos中任一個都可以,在此,我將使用strstr函數,程式碼如下:
  • $str='http://blog.csdn.net/hsd2012';function checkStr1($str,$str2)
    {    return strstr1($str,$str2)?true:false;
    }echo checkStr($str,'csdn');
    解法二:使用正規 
    因為我們只需要判斷是否存在即可,所以選擇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);

    實例2(檢視

    單字定界符
  • ) 
判斷字串」I am a good boy」是否包含單字go 

#首先判斷是單字,而不是字串,因此比較的時候,需要比較是否包含' go ',即在字串go前後有一個空格。 

解析:如果使用非正規比較,只需呼叫上面的checkStr1()函數即可,注意,第二個參數前後要加一個空格,即’ go ‘。如果使用正規則, 

我們可以考慮使用單字定界符\b,那麼$pattern='/\bgo\b/';然後呼叫checkStr2函數即可.

###範例3(考察###反向引用###) ###判斷字串」I am a good boy」是否包含3個相同的字母 ###解析:此時,如果我們不使用正則,將會很難判斷,因為字母太多了,我們不可能去將所有字母分別與該字串比較,那樣工作量也比較大。這時候涉及到了正在的反向引用。在php正規表示式中,透過\n,來表示第n次符合的結果。如\5代表第五次符合的結果。則本題的###$pattern='/(\w).*\1.*\1/';### ###主要注意的是,在使用反向配對的時候都需要使用(),反向匹配時,匹配()裡面出現的字元或字串。 ############php中字串替換######不使用正規######php當替換字串的時候,如果不適用正則,我們通常使用substr 、mb_substr、str_replace、substr_replace關於這幾個函數差異如下表。 ###
修飾符 說明
#單行文字模式
#忽略空白字元
函數符 功能 描述
#str_replace(find, replace,string,count) 使用一個字串取代字串中的另一些字元。 find 必需。規定要找的值。 replace 必需。規定替換 find 中的值的值。 string 必需。規定被搜尋的字串。 count 可選。一個變量,對替換數進行計數。
substr_replace(string,replacement,start,length) 把字串的一部分替換為另一個字串。適合用於替換自定位置的字串。 string 必需。規定要檢查的字串。 replacement 必需。規定要插入的字串。 start 必需。規定在字串的何處開始替換。

使用正規

如果使用正規替換,php中提供了preg_replace _callback和preg_replace 函數,preg_replace 原型如下: 
mixed preg_replace ( mixed pattern,m ixedreplacement , mixed subject[,intlimit = -1 [, int &##count]])#函#述 #在##字串subject中,找出pattern,用replacement 去替換,如果有limit限##### #####制#########替#############l###i###m###i###t##### #####次#########。pregreplacecallbackpregreplace识,不同的是pregreplaceback使用一个回调函数callback来代替replacement.−例1将字符串”hello,中国”中的hello替换为′你好′;如果不是用正则:str=’hello,中国’; str=strreplace(′hello′,′你好′,str) 或是使用str=substrreplace(str,’你好’,0,5) 使用正则 pattern=′/hello/′;str=preg_replace (pattern,′你好′,str); - 例2 去除字符串”gawwenngeeojjgegop”中连续相同的字母

$str='gawwenngeeojjgegop';$pattern='/(.)\1/';$str=preg_replace($pattern,'',$str);

解析:当然这样可能会遇到,当第一次去除了重复了字符串后,又出来重复的字符串。如字符串味’gewwenngeeojjgegop’,针对这中问题,当然,这样的话,通过判断,继续替换下去。

  • 例3 
    将字符串中”age13gegep3iorji65k65k”;中出现的连续两个数字改为第二个数字,如字符串中13被改为3

$str='age13gegep3iorji65k65k';$pattern='/(\d)(\d)/';$str=preg_replace($pattern,'$2', $str);

解析:$n在正则表达式外使用反向引用。n代表第几次匹配到的结果。

php中字符串分割

不适用正则

php提供了explode函数去分割字符串,与其对应的是implode。关于explode原型如下: 
array explode ( string delimiter,stringstring [, int $limit ] ) 
delimiter:边界上的分隔字符。 
string:输入的字符串。 
limit:如果设置了 limit 参数并且是正数,则返回的数组包含最多 limit 个元素,而最后那个元素将包含 string 的剩余部分。如果 limit 参数是负数,则返回除了最后的 -limit 个元素外的所有元素。如果 limit 是 0,则会被当做 1。

使用正则

关于通过正则表达式进行字符串分割,php提供了split、preg_split 函数。preg_split() 函数,通常是比 split() 更快的替代方案。 
array preg_split ( string pattern,stringsubject [, int limit=1[,intflags = 0 ]] )

  • 例题 
    将字符串 ‘http://blog.csdn.net/hsd2012/article/details/51152810‘按照’/’进行分割 
    解法一:

$str='http://blog.csdn.net/hsd2012/article/details/51152810';$str=explode('/', $str);

解法二:

$str='http://blog.csdn.net/hsd2012/article/details/51152810';$pattern='/\//';  /*因为/为特殊字符,需要转移*/$str=preg_split ($pattern, $str);

php中贪婪匹配与惰性匹配

  • 贪婪匹配:就是匹配尽可能多的字符。 
    比如,正则表达式中m.*n,它将匹配最长以m开始,n结尾的字符串。如果用它来搜索manmpndegenc的话,它将匹配到的字符串是manmpndegen而非man。可以这样想,当匹配到m的时候,它将从后面往前匹配字符n。

  • 懒惰匹配:就是匹配尽可能少的字符。 
    有的时候,我们需要并不是去贪婪匹配,而是尽可能少的去匹配。这时候,就需要将其转为惰性匹配。怎样将一个贪婪匹配转为惰性匹配呢?只需要在其后面添加一个”?”即可。如m.*?n将匹配manmpndegenc,匹配到的字符串是man。

函数符 描述
*? 零次或多次,但尽可能少的匹配
+? 一次或多次,但尽可能少的匹配
?? 0次或1次,但尽可能少的匹配
{n,}? 至少n次,但尽可能少的匹配
{n,m}? n到m次 ,但尽可能少的匹配

php正则表达式之回溯与固态分组

回溯

首先我们需要清楚什么是回溯,回溯就像是在走岔路口,当遇到岔路的时候就先在每个路口做一个标记。如果走了死路,就可以照原路返回,直到遇见之前所做过的标记,标记着还未尝试过的道路。如果那条路也走不能,可以继续返回,找到下一个标记,如此重复,直到找到出路,或者直到完成所有没有尝试过的路。首先我们看例题

$str='aageacwgewcaw';$pattern='/a\w*c/i';$str=preg_match($pattern, $str);

看到上面的程序,可能都清楚是什么意思,就是匹配$str是否包含这样一个由”a+0个或多个字母+c”不区分大小写的字符串。但是至于程序怎样去匹配的呢?匹配的过程中,回溯了多少次呢?

匹配过程 接下来操作描述
‘a\w*c’中a匹配到’aageacwgewcaw’中第一个字符a \w进行下一个字符匹配
因为\w是贪婪匹配,会一直匹配到’aageacwgewcaw’中最后一个字符w c进行下一个字符匹配时
‘a\w*c’中c发现没有可以匹配的 于是\w匹配进行第一次回溯,匹配到倒数第二个字符a
‘a\w*c’中c发现还是没有可以匹配的 于是\w匹配进行第二次回溯,匹配到倒数第三个字符c
‘a\w*c’中c匹配成功 匹配结束返回结果

现在,如果我们将pattern为pattern=’/a\w*?c/i’;又会回溯多少次呢?正确答案是回溯四次。

固态分组

固态分组,目的就是减少回溯次数, 使用(?>…)括号中的匹配时如果产生了备选状态,那么一旦离开括号便会被立即 引擎抛弃掉。举个典型的例子如: ‘\w+:’这个表达式在进行匹配时的流程是这样的,会优先去匹配所有的符合\w的字符,假如字符串的末尾没有’:’,即匹配没有找到冒号,此时触发回溯机制,他会迫使前面的\w+释放字符,并且在交还的字符中重新尝试与’:’作比对。但是问题出现在这里: \w是不包含冒号的,显然无论如何都不会匹配成功,可是依照回溯机制,引擎还是得硬着头皮往前找,这就是对资源的浪费。所以我们就需要避免这种回溯,对此的方法就是将前面匹配到的内容固化,不令其存储备用状态!,那么引擎就会因为没有备用状态可用而只得结束匹配过程。大大减少回溯的次数。 
如下代码,就不会进行回溯:

$str='nihaoaheloo';$pattern='/(?>\w+):/';$rs=preg_match($pattern, $str);

当然有的时候,又需慎用固态分组,如下,我要检查$str中是否包含以a结尾的字符串,很明显是包含的,但是因为使用了固态分组,反而达不到我们想要的效果

$str='nihaoahelaa';$pattern1='/(?>\w+)a/';$pattern2='/\w+a/';$rs=preg_match($pattern1, $str);//0$rs=preg_match($pattern2, $str);//1

php中其他常用字符串操作函数

  • 字符串截取截取 
    string substr ( string string,intstart [, int length])stringmbsubstr(stringstr , int start[,intlength = NULL [, string $encoding = mb_internal_encoding() ]] )

  • 字符串中大小写转换 
    strtoupper 
    strtolower 
    ucfirst 
    ucwords

  • 字符串比较 
    -strcmp、strcasecmp、strnatcmp

  • 字符串过滤

  • 字符串翻转 
    strrev($str);

  • 字符串随机排序 
    string str_shuffle ( string $str )

補充

怎樣進行郵箱匹配,url匹配,手機匹配

使用preg_match函數進行匹配,以下內容從TP複製而來。
郵件驗證 
pattern##= /\w ([ .]\w )@\w#([.]\w )\.\w ([. ]\w )∗/'; url符合 

pattern='/^http(s?) :\/\/(?:[A-za-z0-9-] \.) [A-za-z]{2,4}(:\d )?(?:[\/\?#][ \/=\?%\-&~`@[\]\': !\.#\w]*)?/'; 手機驗證 

pattern= /1[3458]\d#10/';


php中正規則的優缺點php中正規在某些時候,能幫我們解決php函數很多困難的匹配或是替換。然後php中正規的效率,往往是我們需要考慮的,所以在某些時候,能不用正則還是盡量不去用它,除非,某些場合必須用到,或者是我們能夠有效減少其回溯次數。

###相關推薦:############PHP正規表示式(增加177手機號碼)############PHP正規表示式分享## ####

以上是PHP 中的正規關係的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn