基礎(chǔ)
定義
正則表達(dá)式是具有特殊語法結(jié)構(gòu)的字符串
Regular Expression reg regexp
作用
- 表單驗證
- 網(wǎng)絡(luò)爬蟲
函數(shù)庫
- PCRE函數(shù)庫
Perl兼容的正則表達(dá)式函數(shù)庫
- POSIX(不推薦使用)
特點
- 語法結(jié)構(gòu)復(fù)雜
- 執(zhí)行效率低
相對于同功能的字符串函數(shù)而言
- 功能強大
語法
語法結(jié)構(gòu)
/正則表達(dá)式/模式修飾符
定界符
- 正則表達(dá)式必須寫在定界符里面
- 除了數(shù)字,字母和反斜杠的任意字符都可以做為定界符,一般用//
- 定界符必須成對出現(xiàn)
$pattern
模式規(guī)則的意思
$pattern="http://";//定界符
$pattern="##";//有效
$pattern="11";//無效 定界符不能是數(shù)字
$pattern="AA";//無效 定界符不能是字母
$pattern="\\";//無效 定界符不能是反斜杠
$pattern="/#";//無效 定界符必須成對出現(xiàn)
原子
- 正則表達(dá)式中的最小原子
- 一個正則表達(dá)式若想有意義,則至少包含一個原子
- 普通字符
a
或1
或-
元字符(特殊的原子)
\s
匹配空格space
\S
匹配非空格\d
匹配數(shù)字decimal
\D
匹配非數(shù)字[^0-9]
\w
匹配單詞(數(shù)字,大小寫,下劃線)[0-9a-zA-Z_]
\W
匹配非單詞[^0-9a-zA-Z]
.
匹配任意字符
$subject="Hello, World";
$pattern='/\s/';//\s匹配空格\
//返回匹配結(jié)果的次數(shù)
//將返回結(jié)果賦值給第三個參數(shù)$matches
echo preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\S/";//\S大s 匹配非空格
echo preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$subject="This it test";
$pattern="#s#";//普通的原子
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$subject= "I am 18";
$pattern="/\d/";//匹配數(shù)字
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\D/";//匹配數(shù)字
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
function isNumber($value){
//思路:如果非數(shù)字匹配不到,則為純數(shù)字
//\D匹配失敗時,匹配對象為純數(shù)字
$pattern="/\D/";
if (!preg_match_all($pattern,$value)){
return true;
}
return false;
}
$value='123adb';
$value='123';
$suc=isNumber($value);
echo $suc?"是數(shù)字":"不是數(shù)字";
$subject="I am_ 18.";
$pattern="/\w/";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\W/";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$subject="I am 18.";
$pattern="/./";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\./";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
轉(zhuǎn)義符(escape)
-
\n
換行符newline -
\t
制表符 - 聲明 雙引號可以解析以上的的轉(zhuǎn)義符,單引號不行
字符組
正字符組
- 可以在正字符組中給出多個原子,多個原子是"或"的關(guān)系
$pattern="/[is]/";//匹配字母i或者字母s
- 常用的字符組(匹配范圍)
[0-9]
相當(dāng)于\d
[a-z]
[A-Z]
負(fù)字符組
[^xxxxxx]
量詞
- 用來修飾正則表達(dá)式出現(xiàn)的次數(shù)(數(shù)量)
- 語法
{n}
精確匹配==n==位 -
{n,}
開區(qū)間匹配 -
{n,m}
閉區(qū)間匹配,其中n,m都為正整數(shù),n<m
$subject="This iis test";
$pattern="/i{2}/";
//匹配多位(,后面沒有空格)
$pattern="/i{1,}/";
$pattern="/i{2,3}/";//匹配2位到3位
-
?
匹配0
或1
位{0,1}
-
*
匹配0
位或多位{0,}
-
+
匹配1
位或多位{1,}
$pattern="/s\s?/";//匹配"s"或"s空格" ?代表0或1位
$pattern="/s\s*/";//*匹配0到多位
$pattern="/s\s+/";//+匹配1到多位
//匹配手機號
//17375821270
//手機號是11位的數(shù)字 \d{11}
//手機號的第一位數(shù)字為1 1\d{10}
//13X 15X 17X 18X
//手機號第二位可能的數(shù)字是3578 [3578]
//手機號第三位也有號段(暫不考慮)
//177-1234-1234 1[3578]\d-?\d{4}-?\d{4}
//17712341234
//0177-1234-1234 0?1[3578]\d-?\d{4}-?\d{4}
//+86 0177-1234-1234 (暫時省略)
//匹配開頭和結(jié)尾(邊界),使用定位點符號 ^ $ ^0?1[3578]\d-?\d{4}-?\d{4}$
// /^正則表達(dá)式$/
//思路:
//1.首先分析目標(biāo)字符串的規(guī)律(模式)
//2.將規(guī)律(模式)翻譯成正則表達(dá)式
//3.驗證
function isMobile($mobile){
$pattern="/^0?1[3578]\d-?\d{4}-?\d{4}$/";
if(preg_match($pattern,$mobile)){
return true;
}
return false;
}
$mobile="0173-7582-1270";
$suc=isMobile($mobile);
echo $suc?$mobile."手機號合法":$mobile."手機號非法";
//數(shù)字規(guī)律
//郵政編碼
//身份證號
//區(qū)號
//QQ號
//....
定位點
- ==
^
== 匹配開頭\A
- $ 匹配結(jié)尾
\Z
-
\b
匹配邊界 -
\B
匹配非邊界
//定位點
//^匹配開頭
//$匹配結(jié)尾
$subject="This is test";
$pattern='/^T/';//匹配左側(cè)邊界
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/t$/";//匹配右側(cè)邊界
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/s\b/";//匹配右側(cè)為邊界的小寫字母s
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\Bs\B/";//匹配非邊界小寫字母s
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
選擇路徑
-
|
或,a|b
$subject="This is test";
$pattern="/is|t/";//匹配is或者t
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
模式修飾符
-
i
"http://i"
忽略大小寫
$subject="This is test";
$pattern="/t/i";//忽略大小寫,匹配字母t
//應(yīng)用場景:對大小寫不敏感時,使用模式修飾符i
//例如:<table>或者<TABLE> 都是有效的HTML標(biāo)簽
-
U
ungreedy
非貪婪模式(懶惰模式)- PHP正則默認(rèn)是貪婪模式
- 貪婪:在滿足條件的前提下盡可能多的匹配
- 可以混合使用
Ui
- ==
.*
== 貪婪模式 - ==
.*?
== 非貪婪模式(量詞加問號限定死)
//貪婪模式
$subject="<td>zhangsan</td><td>lisi</td>";
$pattern="/<td>.+<\/td>/";//\轉(zhuǎn)義 不然和定界符沖突
/*
* <pre>Array
(
[0] => Array
(
[0] => <td>zhangsan</td><td>lisi</td>
)
)
</pre>*/ //貪婪模式 因為 <td>zhangsan</td><td>lisi</td> zhangsan</td><td>lisi 也滿足條件下盡可能多的匹配
//非貪婪模式
$pattern="/<td>.+<\/td>/U";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
/*
*
* Array
(
[0] => Array
(
[0] => zhangsan
[1] => lisi
)
)
*/ //非貪婪模式
捕獲組
-
(XXXX)
描述正則表達(dá)式中的子表達(dá)式- 編號為0 的結(jié)果,匹配整個正則表達(dá)式
- 然后從1開始,按照小括號的順序從左向右依次排序
- 引用
- 正向引用
- 在代碼中(正則表達(dá)式之外)使用匹配成為正向引用
- 反向引用
- 語法
\number
number匹配結(jié)果對應(yīng)的索引值 - 反向引用使用的是匹配結(jié)果,而不是正則表達(dá)式本身
- 語法
- 正向引用
// 03_group.php
// 捕獲組 ()
// 假定該日期是一個生日
$subject = "2017-12-07";
// 日期格式分析:
// 年: 1900-現(xiàn)在 (19|20)\d{2} \d{4}
// 19\d{2}|200\d|201[0-7]
// 月: 01 02 .... 09 10 11 12
// 十位數(shù): 0?[1-9]|1[0-2]
//
// 日: 01 ... 09
// 10 ... 19
// 20 ... 29
// 30 31
// 0?[1-9]|1[0-9]|2[0-9]|3[01]
// 0?[1-9]|[12][0-9]|3[01]
// 0?[1-9]|[12]\d|3[01]
// $pattern = "/(YYYY)-(MM)-(DD)/";
// $pattern = "/(YYYY)-((MM)-(DD))/";
$pattern = "/(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])/";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
-
(?:xxxx)
非捕獲組
匹配函數(shù)
preg_match_all($pattern,$subject,$matches);
返回匹配的次數(shù),二維數(shù)組
preg_match($pattern,$subject);
返回匹配的結(jié)果,一維數(shù)組
查找替換
preg_replace($pattern,$replacement,$matches)
和str_replace($search,$replacement,$matches)
$subject="This is test";
//將字符串中的空格替換成下劃線
echo str_replace(" ","_",$subject)."<hr>";
$pattern="/\s/";
echo preg_replace($pattern,"_",$subject)."<hr>";
//聲明:
//如果普通字符串函數(shù)與正則表達(dá)式函數(shù)能夠完成同樣的功能;
//則優(yōu)先使用普通字符串函數(shù)(正則效率低)
$subject="This2 i4s te6st";
//將字符串中的數(shù)字替換成下劃線
$pattern="/\d/";//匹配數(shù)字
echo preg_replace($pattern,"_",$subject)."<hr>";
//將html標(biāo)簽去掉
//<p>hello</p>
正則分割
array pre_split($pattern,$subject)
和array explode($delimiter,$string)
$subject="This is test";
$arr1=explode(" ",$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";
$pattern="/\s/";
$arr1=preg_split($pattern,$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";
//聲明:
//如果普通字符串函數(shù)與正則表達(dá)式函數(shù)能夠完成同樣的功能;
//則優(yōu)先使用普通字符串函數(shù)(正則效率低)
//根據(jù)右側(cè)邊界字母s進行分割
$pattern="/s\b/";
$arr1=preg_split($pattern,$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";
//普通函數(shù)達(dá)不到要求,必須要正則來寫了
返回匹配模式的數(shù)組條碼
preg_grep($pattern,$input);
//匹配數(shù)組元素
//grep =Global Regular ExPression
// 全局正則表達(dá)式
$pattern="/te/";
$input=array("time","term","team");
$arr=preg_grep($pattern,$input);
echo "<pre>";
print_r($arr);
echo "</pre>";