摘要:是決定正則表達式匹配規(guī)則的主要部分。二分隔符分隔符的選擇當使用函數的時候,正則表達式必須由分隔符閉合包裹。果分隔符經常在正則表達式內出現,最好使用其他分隔符來提高可讀性。需要將一個字符串放入正則表達式中使用時,可以用函數對其進行轉義。
一、簡介 1. 什么是正則表達式
正則表達式(Regular Expression)就是用某種模式去匹配一類字符串的一種公式。
正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規(guī)則的字符串。
正則表達式是繁瑣的,但它是強大的,學會之后的應用會讓你除了提高效率外,會給你帶來絕對的成就感。只要認真閱讀本教程,加上應用的時候進行一定的參考,掌握正則表達式不是問題。
許多程序設計語言都支持利用正則表達式進行字符串操作。
分割,查找,匹配,替換字符串
3. PHP中的正則表達式在PHP中有兩套正則表達式函數庫,兩者功能相似,只是執(zhí)行效率略有差異:
一套是由 PCRE(Perl Compatible Regular Expression) 庫提供的。使用“preg_”為前綴命名的函數;
一套由 POSIX(Portable Operating System Interface of Unix )擴展提供的。使用以“ereg_”為前綴命名的函數;
PCRE來源于Perl語言,而Perl是對字符串操作功能最強大的語言之一,PHP的最初版本就是由Perl開發(fā)的產品。
PCRE語法支持更多特性,比POSIX語法更強大。因此,本文主要介紹 PCRE 語法的正則表達式
在PHP中,一個正則表達式分為三個部分:分隔符、表達式和模式修飾符。
分隔符分隔符可以使用除字母、數字、反斜線()和空白字符之外的任意 ascii 字符。
最常用的分隔符有正斜線(/)、hash符號(#) 以及取反符號(~)。
有一些特殊字符和非特殊的字符串組成。是決定正則表達式匹配規(guī)則的主要部分。
模式修飾符用于開啟和關閉某些特定的功能/模式。
二、分隔符 1. 分隔符的選擇當使用 PCRE 函數的時候,正則表達式必須由分隔符閉合包裹。
分隔符可以使用除字母、數字、反斜線()和空白字符之外的任意 ascii 字符。
最常用的分隔符有正斜線(/)、hash符號(#) 以及取反符號(~)。
/foo bar/ (合法) #^[^0-9]$# (合法) +php+ (合法) %[a-zA-Z0-9_-]% (合法)
#[a-zA-Z0-9_-]/ (非法,兩邊的分隔符不同) a[a-zA-Z0-9_-]a (非法,分隔符不能是字母) [a-zA-Z0-9_-] (非法,分隔符不能是反斜線(``))
除了上面提到的分隔符,也可以使用括號樣式的分隔符,左括號和右括號分別作為開始和結束 分隔符。
{this is a pattern}2. 分隔符的使用
如果分隔符 在正則表達式中使用,它必須使用反斜線()進行轉義。
果分隔符經常在正則表達式內出現, 最好使用其他分隔符來提高可讀性。
/http:/// #http://#
需要將一個字符串放入正則表達式中使用時,可以用 preg_quote() 函數對其進行轉義。 它的第二個參數(可選)可以用于指定需要被轉義的分隔符。
//在這個例子中,preg_quote($word) 用于保持星號和正斜杠(/)原文涵義,使其不使用正則表達式中的特殊語義。 $textBody = "This book is */very/* difficult to find."; $word = "*/very/*"; $reg = "/" . preg_quote($word, "/") . "/"; echo $reg; // 輸出 "/*/very/*/" echo preg_replace ($reg, "" . $word . "", $textBody); // 輸出 "This book is */very/* difficult to find."
可以在結束分隔符后面增加模式修飾符來影響匹配效果。
下面的例子是一個大小寫不敏感的匹配
#[a-z]#i三、元字符 1. 轉義符
字符 | 描述 |
---|---|
將下一個字符標記為一個特殊字符、或一個原義字符、或一個 向后引用。 例如,"n" 匹配字符 "n"。"n" 匹配一個換行符。序列 "" 匹配 "" 而 "(" 則匹配 "("。 |
字符 | 描述 |
---|---|
^ | 匹配輸入字符串的開始位置 (或在多行模式下是行首) |
$ | 匹配輸入字符串的結束位置 (或在多行模式下是行尾) |
匹配一個單詞邊界,即字與空格間的位置 | |
B | 非單詞邊界匹配 |
字符 | 描述 |
---|---|
* | 匹配前面的子表達式零次或多次。 例如,zo 能匹配 "z" 以及 "zoo"。 等價于{0,}。 |
+ | 匹配前面的子表達式一次或多次。 例如,"zo+" 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價于 {1,}。 |
? | 當該字符作為量詞,表示匹配前面的子表達式零次或一次。 例如,"do(es)?" 可以匹配 "do" 或 "does" 。? 等價于 {0,1}。 |
{n} | n 是一個非負整數。匹配確定的 n 次。 例如,"o{2}" 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的兩個 o。 |
{n,} | n 是一個非負整數。至少匹配n 次。 例如,"o{2,}" 不能匹配 "Bob" 中的 "o",但能匹配 "foooood" 中的所有 o。"o{1,}" 等價于 "o+"。"o{0,}" 則等價于 "o*"。 |
{n,m} | m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。 例如,"o{1,3}" 將匹配 "fooooood" 中的前三個 o。"o{0,1}" 等價于 "o?"。請注意在逗號和兩個數之間不能有空格。 |
字符 | 描述 | |
---|---|---|
d | 匹配一個數字字符。等價于 [0-9]。 | |
D | 匹配一個非數字字符。等價于 [^0-9]。 | |
w | 匹配字母、數字、下劃線。等價于 [A-Za-z0-9_]。 | |
W | 匹配非字母、數字、下劃線。等價于 [^A-Za-z0-9_]。 | |
s | 匹配任何空白字符,包括空格、制表符、換頁符等等。等價于 [ f v]。 | |
S | 匹配任何非空白字符。等價于 [^ f v]。 | |
. | 匹配除換行符(n、r)之外的任何單個字符。 要匹配包括 "n" 在內的任何字符,請使用像"(. |
n)"的正則表達式。 |
字符 | 描述 |
---|---|
匹配一個換行符。等價于 x0a 和 cJ。 | |
匹配一個回車符。等價于 x0d 和 cM。 | |
匹配一個制表符。等價于 x09 和 cI。 |
字符 | 描述 |
---|---|
| | 豎線字符 | 可以匹配多選一的情況。 例如,"z|food" 能匹配 "z" 或 "food"。"(z|f|g)ood" 則匹配 "zood"、"food"或 "good"。 |
字符 | 描述 |
---|---|
[x|y] | 匹配 x 或 y。 例如,"z|food" 能匹配 "z" 或 "food"。"(z|f)ood" 則匹配 "zood" 或 "food"。 |
[xyz] | 字符集合。匹配所包含的任意一個字符。 例如, [abc] 可以匹配 "plain" 中的 "a"。 |
[^xyz] | 負值字符集合。匹配未包含的任意字符。 例如, [^abc] 可以匹配 "plain" 中的"p"、"l"、"i"、"n"。 |
[a-z] | 字符范圍。匹配指定范圍內的任意字符。 例如,[a-z] 可以匹配 "a" 到 "z" 范圍內的任意小寫字母字符。 |
[^a-z] | 負值字符范圍。匹配任何不在指定范圍內的任意字符。 例如,[^a-z] 可以匹配任何不在 "a" 到 "z" 范圍內的任意字符。 |
字符 | 描述 |
---|---|
? | 當該字符緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面時,匹配模式是非貪婪的。 非貪婪模式盡可能少的匹配所搜索的字符串,而默認的貪婪模式則盡可能多的匹配所搜索的字符串。 例如,對于字符串 "oooo","o+?" 將匹配單個 "o",而 "o+" 將匹配所有 "o"。 |
字符 | 描述 |
---|---|
(pattern) | 匹配 pattern 并獲取這一匹配。要匹配圓括號字符,請使用 ( 或 )。 |
(?:pattern) | 匹配 pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以后使用。這在使用 "或" 字符 (|) 來組合一個正則表達式的各個部分是很有用。 例如, "industr(?:y|ies) 就是一個比 "industry|industries" 更簡略的表達式。 |
(?=pattern) | 正向肯定預查(look ahead positive assert),在任何匹配pattern的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。 例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。預查不消耗字符,也就是說,在一個匹配發(fā)生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始。 |
(?!pattern) | 正向否定預查(negative assert),在任何不匹配pattern的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。 例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。預查不消耗字符,也就是說,在一個匹配發(fā)生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始。 |
(?<=pattern) | 反向(look behind)肯定預查,與正向肯定預查類似,只是方向相反。 例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。 |
(? | 反向否定預查,與正向否定預查類似,只是方向相反。 例如"(? |
如果設置了這個修飾符,正則表達式中的字母會進行大小寫不敏感匹配。
2. m(多行模式)默認情況下,PCRE 認為目標字符串是由單行字符組成的(然而實際上它可能會包含多行)。
"行首"元字符 (^) 僅匹配字符串的開始位置, 而"行末"元字符 ($) 僅匹配字符串末尾, 或者最后的換行符(除非設置了 D 修飾符)。
當這個修飾符設置之后,“行首”元字符 (^) 和“行末”元字符 ($) 就會匹配目標字符串中任意換行符之前或之后,另外,還分別匹配目標字符串的最開始和最末尾位置。
如果目標字符串 中沒有 "n" 字符,或者正則表達式中沒有出現 ^ 或 $,設置這個修飾符不產生任何影響。
3. s(點號通配模式)默認情況下,點號(.)不匹配換行符。
如果設置了這個修飾符,正則表達式中的點號元字符匹配所有字符,包含換行符。
這個修飾符與前面提到的 ? 作用相同,使正則表達式默認為非貪婪匹配。
在使用U修飾符的情況下,再在量詞后加 ? ,可以使其轉為貪婪匹配(負負得正)。
在非貪婪模式,通常不能匹配超過 pcre.backtrack_limit 的字符。貪婪模式
$str = "abcdef"; $pattern = "|(.*)|"; preg_match_all($pattern, $str, $matches);
.*會匹配 abcdef
在使用U修飾符的情況下,再在量詞后加 ? ,負負得正,依然是貪婪匹配
$str = "abcdef"; $pattern = "|(.*?)|U"; preg_match_all($pattern, $str, $matches);
.*會匹配 abcdef
非貪婪模式方法一、使用 ? 轉為非貪婪模式
$str = "abcdef"; $pattern = "|(.*?)|"; preg_match_all($pattern, $str, $matches);
.*會分別匹配 abc,def
方法二、使用修飾符 U 轉為非貪婪模式
$str = "abcdef"; $pattern = "|(.*)|U"; preg_match_all($pattern, $str, $matches);
.*會分別匹配 abc,def
5. u(支持UTF-8轉義表達)此修正符使正則表達式和目標字符串都被認為是 utf-8 編碼。
無效的目標字符串會導致 preg_* 函數什么都匹配不到;無效的正則表達式字符串會導致 E_WARNING 級別的錯誤。
$str = "中文"; $pattern = "/^[x{4e00}-x{9fa5}]+$/u"; if (preg_match($pattern, $str)) { echo "該字符串全是中文"; } else { echo "該字符串不全是中文"; }6. D(結尾限制)
默認情況下,如果使用 $ 限制結尾字符,當字符串以一個換行符結尾時, $符號還會匹配該換行符(但不會匹配之前的任何換行符)。
如果設置這個修飾符,正則表達式中的 $ 符號僅匹配目標字符串的末尾。
如果設置了修飾符 m,這個修飾符被忽略。
如果設置了這個修飾符,正則表達式中的沒有經過轉義的或不在字符類中的空白數據字符總會被忽略, 并且位于一個未轉義的字符類外部的#字符和下一個換行符之間的字符也被忽略。
8. A如果設置了這個修飾符,正則表達式被強制為"錨定"模式,也就是說約束匹配使其僅從 目標字符串的開始位置搜索。
9. S當一個正則表達式需要多次使用的時候,為了得到匹配速度的提升,值得花費一些時間對其進行一些額外的分析。
如果設置了這個修飾符,這個額外的分析就會執(zhí)行。
當前,這種對一個正則表達式的分析僅僅適用于非錨定模式的匹配(即沒有多帶帶的固定開始字符)。
使用 ( ) 標記的開始和結束的多個原子,不僅是一個獨立的單元,也是一個子表達式。
在一個 ( ) 中的子表達式外面,反斜線緊跟一個大于 0 的數字,就是對之前出現的某個子表達式的后向引用。
后向引用用于重復搜索前面某個 ( ) 中的子表達式匹配的文本。
(sens|respons)e and 1ibility 將會匹配 ”sense and sensibility” 和 ”response and responsibility”, 而不會匹配 ”sense and responsibility”
2. 在PCRE函數中使用反向引用abcdef"; $pattern = "/(.*)(.*)/"; $replace = preg_replace($pattern, "1", $str); echo $replace . " "; $replace = preg_replace($pattern, "2", $str); echo $replace . " ";
輸出:
abc def六、正則表達式常用PCRE函數
PHP官網的講解已經很詳細了,這里不再做多余的論述執(zhí)行正則表達式匹配 preg_match() 執(zhí)行正則表達式全局匹配 preg_match_all() 執(zhí)行一個正則表達式的搜索和替換 preg_replace() 執(zhí)行一個正則表達式搜索并且使用一個回調進行替換 preg_replace_callback() 執(zhí)行多個正則表達式搜索并且使用對應回調進行替換 preg_replace_callback_array() 通過一個正則表達式分隔字符串 preg_split() 七、應用實踐 1. 正則表達式匹配中文
UTF-8漢字編碼范圍是 0x4e00-0x9fa5
在ANSI(GB2312)環(huán)境下,0xb0-0xf7,0xa1-0xfe
UTF-8要使用 u模式修正符 使模式字符串被當成 UTF-8
在ANSI(GB2312)環(huán)境下,要使用chr將Ascii碼轉換為字符
ANSI(GB2312)2. 正則表達式匹配頁面中所有img標簽中的src的值。/i"; preg_match($pattern, $str, $match); var_dump($match);
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/29930.html
摘要:聲明靜態(tài)變量時不能用表達式的結果對其賦值正確錯誤使用表達式的結果賦值錯誤使用表達式的結果賦值靜態(tài)變量與遞歸函數靜態(tài)變量提供了一種處理遞歸函數的方法。 一、變量的定義 1. 變量的命名規(guī)則 變量名可以包含字母、數字、下劃線,不能以數字開頭。 $Var_1 = foo; // 合法 $var1 = foo; // 合法 $_var1 = foo; // 合法 $Var-1 = foo; /...
摘要:除法運算符總是返回浮點數。取模運算符的結果和被除數的符號正負號相同。使用位運算符時要特別注意優(yōu)先級。太空船運算符組合比較符當小于等于大于時分別返回一個小于等于大于的值。遞增遞減運算符不影響布爾值。 一、算術運算符 1. 概覽 例子 名稱 結果 $a + $b 加法 $a 和 $b 的和。 $a - $b 減法 $a 和 $b 的差。 $a * $b 乘法 $a 和 ...
摘要:使用中文函數名和變量名面積長寬長寬面積合法,輸出中文符號函數名。類型聲明類型聲明允許函數在調用時要求參數為特定類型。需要使用自己的包裝函數來將這些結構用作可變函數。匿名函數目前是通過類來實現的。 一、函數的定義 1. 函數的命名規(guī)則 函數名可以包含字母、數字、下劃線,不能以數字開頭。 function Func_1(){ } //合法 function func1(){ } //合法 ...
摘要:支持崩潰后的安全恢復。的使用場景更新密集的表存儲引擎特別適合處理多重并發(fā)的更新請求。外鍵約束支持外鍵的存儲引擎只有。引擎是及之前版本的默認存儲引擎。文件存儲表的索引。引擎存儲引擎是引擎的變種。 MySQL基礎知識點整理 - 存儲引擎 0. 查看 MySQL 支持的存儲引擎 可以在 mysql 客戶端中,使用 show engines; 命令可以查看MySQL支持的引擎: mysql> ...
閱讀 1369·2021-11-15 11:45
閱讀 3136·2021-09-27 13:36
閱讀 2880·2019-08-30 15:54
閱讀 999·2019-08-29 12:38
閱讀 2920·2019-08-29 11:22
閱讀 2999·2019-08-26 13:52
閱讀 2043·2019-08-26 13:30
閱讀 599·2019-08-26 10:37