《PHP之正則表達式系統總結》

爲什麼選擇PHP語言來寫正則表達式這篇博客呢?嘿嘿嘿,因爲PHP正則表達式稍微懂一點,如果是其它語言的正則表達式,都是差不多的。
一、正則表達式函數解析
PHP中常用的正則表達式函數:

int preg_match($pattern, $subject);
preg_match_all($pattern, $subject, array &$matches);
preg_replace($pattern, $replacement, $subject);
preg_filter($pattern, $replacement, $subject);
preg_grep($pattern, array $input);
preg_split($pattern, $subject);
preg_quote($str);

參數說明:
pattern= subject = 匹配的目標數據
1,preg_match(pattern, subject, [array &matches]);pregmatchall( pattern, subject, array & matches);
注意:preg_match()的第三個參數是可選的,後邊那個函數的第三個參數是必選的。注意那個&,表示按引用傳遞
preg_match()在匹配subject subject中所有符合pattern matches數組中.這兩個函數都有一個整形的返回值,即匹配到的次數。

//需要數據輸出調試的時候,我們就用這個寫好的show函數
function show($var = null){
    if(empty($var)){
        echo 'null';
    }elseif (is_array($var)||is_object($var)) {
        //array,object
        echo '<pre>';
        print_r($var);
        echo '</pre>';

    }else{
        //string,int,float
        echo $var;
    }
}

/*
1,preg_match($pattern, $subject, [array &$matches]);和preg_match_all($pattern, $subject, array &$matches);
*/
$pattern = '/[0-9]/';//表示匹配0到9之間的數字
$subject = '45ghghg545hg5jh';
$m1 = $m2 = array();
$t1 = preg_match($pattern, $subject, $m1);
$t2 = preg_match_all($pattern, $subject, $m2);
show($m1);
echo '<hr />';
show($m2);
echo ‘<hr />’;
show($t1.’||’.$t2);

執行結果:
這裏寫圖片描述
我會回看見preg_match()返回的是一位數組,而preg_match_all()返回的是一個二維數組
2,preg_replace(pattern, replacement, subject)pregfilter( pattern, replacement, subject)
這兩個函數的功能極其的相似,參數完全相同,只是返回結果有一點點的區別。當使用pattern subject中進行匹配,匹配的結果會替換成$replacement.(說到這個替換功能,小夥伴們有必要將str_replace()函數複習一下http://www.w3school.com.cn/php/func_string_str_replace.asp

$pattern = '/[0-9]/';//表示匹配0到9之間的數字
$subject = '45ghghg545hg5jh';
$replacement = "^_^";

$str1 = preg_replace($pattern, $replacement, $subject);
$str2 = preg_filter($pattern, $replacement, $subject);

show($str1);
echo '<hr />';
show($str2);

執行結果:
這裏寫圖片描述
我們都知道搜索目標和替換的數據兩個變量,不僅僅支持字符串,還支持數組,preg_replace()也是支持數組替換的

$pattern = array('/[0123]/', '/[456]/', '/[789]/');
$subject = '1ghghg45hg8jh';
$replacement = array('^_^', '*_*', '$_$');//表示當匹配到0123中的任意一個數字時,就替換成^_^.如果匹配到456中的任意一個數字就替換成*_*

$str1 = preg_replace($pattern, $replacement, $subject);
$str2 = preg_filter($pattern, $replacement, $subject);

show($str1);
echo '<hr />';
show($str2);

執行結果:
這裏寫圖片描述
到現在我們還是沒有看到兩個函數返回值餓區別在哪裏,現在,我們把$subject也換成數組

$pattern = array('/[0123]/', '/[456]/', '/[789]/');
//$subject = '1ghghg45hg8jh';
$subject = array('were', 't4bd', '9fdfdgd', 'r', '1df');
$replacement = array('^_^', '*_*', '$_$');//表示當匹配到0123中的任意一個數字時,就替換成^_^.如果匹配到456中的任意一個數字就替換成*_*

$str1 = preg_replace($pattern, $replacement, $subject);
$str2 = preg_filter($pattern, $replacement, $subject);

show($str1);
echo '<hr />';
show($str2);

執行結果:
這裏寫圖片描述
這個時候我們就看到區別了,第一個函數會將數組中沒有與$pattern匹配的字符串也保存在數組中,而第二個函數只將匹配到的字符串保存在數組中,輸出來
3,preg_grep(pattern,array input)
他就是將匹配到的字符串保存到數組中,然後返回出來,不進行匹配

$pattern = '/[0-9]/';//表示匹配09之間的數字
//$pattern = array('/[0123]/', '/[456]/', '/[789]/');
//$subject = '1ghghg45hg8jh';
$subject = array('were', 't4bd', '9fdfdgd', 'r', '1df');
//$replacement = array('^_^', '*_*', '$_$');//表示當匹配到0123中的任意一個數字時,就替換成^_^.如果匹配到456中的任意一個數字就替換成*_*

$arr = preg_grep($pattern, $subject);

show($arr);

執行結果:
這裏寫圖片描述
4,preg_split(pattern, subject)
通過pattern subject字符串,然後把分割得到的多個字符串放置到數組中返回出來(說到分割,大家就會想到explode()函數,那麼小夥伴們有必要回憶一下http://www.w3school.com.cn/php/func_string_explode.asp

$pattern = '/[0-9]/';//表示匹配09之間的數字
//$pattern = array('/[0123]/', '/[456]/', '/[789]/');
//$subject = '1ghghg45hg8jh';
$subject = 'shu3lv,5together';
//$replacement = array('^_^', '*_*', '$_$');//表示當匹配到0123中的任意一個數字時,就替換成^_^.如果匹配到456中的任意一個數字就替換成*_*

$arr = preg_split($pattern, $subject);

show($arr);

執行結果:
這裏寫圖片描述
5,preg_quote($str)
將一個字符串中的正則表達式運算符進行轉義
轉義主要是爲了防止運算符和我們要輸出的字符串發生混淆,在正則表達式中,有這些運算符(.+*?[^]$(){}=!<>|:-),在正則表達式中直接書寫這些字符,PHP的解析器會將它當做一個正則的運算符來看待,有的時候,比如我想匹配一個{},但是這個{}又是正則表達式中的一個運算符,這個時候我們就需要在前邊加一個\進行轉義,告訴PHP的解析器不要產生混淆

$str = "jhj{dfg}[5455]";

$arr = preg_quote($str);

show($arr);

執行結果:
這裏寫圖片描述
總結:總結一下這幾個PHP正則表達式中的幾個函數
1,都是以preg_開頭
2,除了preg_quote()函數外,第一個參數都是正則表達式
3,preg_match() 通常用於表單驗證,如果匹配到,返回1 ,否則返回0
4,preg_replace()通常用於非法詞語過濾等
二、正則表達式基本語法
概述:
1,界定符
2,原子
3,量詞
4,邊界控制
5,模式單元
(1)界定符
表示正則表達式開始和結束的位置 比如 $pattern = ‘[0-9]\’ 有兩個斜槓將表達式夾在中間(它不是正則表達式的組成部分,它只是告訴PHP解析器,正則表達式是從什麼時候開始和什麼時候結束的)(其實也可以用#[0-9]#、{[0-9]},爲了避免產生歧義,大家還是使用[0-9]\的方式)
福利:爲了學習正則表達式的簡單和方便,這裏就推薦一個輔助書寫正則表達式的神器:regexpal,這個是用html和css開發的,直接在瀏覽器中打開就能運行(http://wpjam.qiniudn.com/tool/regexpal/)
這裏寫圖片描述
(2)原子
原子是正則表達式中最小的匹配單位,通常它只是Unicode編碼表中的某一個字符。原子分爲可見原子和不可見原子
**可見原子:**Unicode編碼表中,用鍵盤輸出後肉眼可見的字符 例如:標點、英文字母數字、漢子、日文、法文、數理化公式符號等等
**不可見原子:**Unicode編碼表中,用鍵盤輸出後肉眼看不見的字符 例如:換行符(\n)、回車(\r)、製表符(\t)、空格等等。正則表達式同樣可以匹配到這些不可見原子
這裏寫圖片描述
由於在匹配中文的時候可能會由於編碼的問題,出現一些未知的錯誤,所以我們可以將中文轉換成Unicode編碼,編碼轉換工具:http://tool.chinaz.com/tools/unicode.aspx
這裏寫圖片描述
當我們要匹配的符號是一個正則表達式的符號時,在前邊加一個’\’進行轉義就可以匹配到了
上邊說的這些都是可見原子,下邊我們說一下不可見原子
我們在regexpal工具中直接輸入空格就行,就可以匹配到空格。匹配製表符,輸入’\t’即可。
下邊我們說一下:元字符(它主要做兩件事,1,定義原子的篩選方式,2,將比較類似的原子進行歸類,給出一個縮寫來簡化正則表達式 比如英文字符數字 用\w)
原子的篩選方式:(1)| 匹配兩個或者多個分支選擇(2)[] 匹配方括號中的任意一個原子(3)[^] 匹配除方括號中的原子之外的任意字符
這裏寫圖片描述
如果想使用 | 的方式匹配到Duang~和duang~,這樣寫 Duang~|duang~ ,|是對兩邊的整串字符拿來匹配,而不是拿某一個來匹配(上邊這幾個元字符大家都用那個工具試一下,我就不一一截圖了)
原子的集合:
. 匹配除換行符之外的任意字符
\d 匹配任意一個十進制數字,即[0-9]
\D 匹配任意一個非十進制數字,即[^0-9]
\s 匹配一個不可見原子,即[\f\r\t\n\v]
\S 匹配一個可見原子,即[^\f\r\t\n\v]
\w 匹配任意一個數字、字母或下劃線,即[0-9a-zA-Z]
\W 匹配任意一個數字、字母或下劃線,即[^0-9a-zA-Z]
大家可以使用上邊那個工具來嘗試一下
(3)量詞
{n}表示其前邊的原子恰好出現n次
{n,} 表示其前邊的原子最少出現n次
{n,m}表示其前邊的原子最少出現n次,最多出現m次
*表示匹配0次、1次或者多次其前邊的原子,即{0,}
+表示匹配1次或者多次其前邊的原子,即{1,}
? 表示匹配0次或1次其前邊的原子,即{0,1}
大家給這幾個拿去多練就好了
(4)邊界控制和模式單元
^ 匹配字符串開始的位置
$ 匹配字符串結束的位置
() 匹配其中的整體爲一個原子
看例子來說明:
這裏寫圖片描述
那個$也是同理
那麼模式單元的()是如何使用呢,假設我要匹配Duang~ duang~
這裏寫圖片描述
到這裏,正則表達式的基本語法就說完了,後邊會有綜合實例來進行鞏固
三、正則表達式中的修正模式
1,貪婪匹配
匹配結果存在歧義時取其長
看下邊的代碼:

$pattern = '/shulv.+123/';//這個就是說,匹配以shulv開頭,後邊跟除換行符外的任意字符,且該字符出現1次或多次,並且以123結尾
$subject = 'I love shulv_123123123123123';
//當我們匹配到這個字符串的時候,我們發現,匹配到shulv_123可以,匹配到shulv_123123123123123也可以,這個時候就出現了歧義,這個時候,默認的使用的是貪婪模式,也就是匹配到最長的那個
$matches = array();

preg_match($pattern, $subject,$matches);

show($matches);

執行結果:
這裏寫圖片描述
2,懶惰匹配
匹配結果存在歧義時取其短
還是上邊的例子,如果我們想使用懶惰模式,可以直接在patternU pattern = ‘/shulv.+123/U’;
這個時候匹配到的結果就是shulv_123

常見修正模式:
U 懶惰匹配
u 貪婪匹配
I 忽略英文字母大小寫
x 忽略空白
s 讓元字符’ . ’匹配包括換行符在內的所有字符
這幾個,小夥伴們自行練習
注意:如果你想讓兩種修正模式同時使用,可以這樣寫 ‘/ShUlv.+123/Ui’;這樣就可以既忽略大小寫,又使用懶惰模式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章