PHP正則表達式
平時用的不多,但是要用的時候總是要打開相關資料看一下,這次就對php的正則表達式做個總結,加深記憶并以便日后參閱,
其他語言不保證通用,比如javascript支持的正則就沒有php那么多,
元字符:
. 匹配除換行符以外的任意字符
\w 匹配字母數字或下劃線或漢字
\s 匹配任意空白符
\d 匹配數字
\b 匹配單詞的開始或結束
^ 匹配字符串的開始
$ 匹配字符串的結束
- 表示范圍
[] 匹配括號中的任意一個字符
量詞:
* 重復0次或更多次
+ 重復1次或更多次
? 重復0次或1次
{n} 重復n次
{n,} 重復n次或更多次
{n,m} 重復n到m次
轉義:: \ 一般用來轉義特殊字符,比如元字符 使用\* 就能匹配*了
反義: 一般情況,能不用反義的地方就不用 ,反義的范圍太大了 會有很多你沒想到的情況,容易出錯
\W 匹配任意不是字符,數字,下劃線,漢字的字符
\S 匹配任意不是空白的字符
\D 匹配任意非數字的字符
\B 匹配不是單詞開頭或結束的位置
[^x] 匹配除了x以外的任意字符
[^qwe] 匹配除了qwe這幾個字符以外的字符
分支: |
(x|h|yo)at 匹配xat hat yoat
分組:
(exp) 匹配exp,并不或文本到自動命名的組里
(?<name>exp) 匹配exp,并捕獲文本到名稱為name的組里 也可寫成 (? 'name' exp)
(?:exp) 匹配exp,不捕獲匹配的文本,也不分配組號
斷言: 標準的說應該叫環視,斷言是根據意思好記寫的 (斷言也是一種分組,所以也會被分配組號)
(?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
反向引用: \1 --->引用組號為1的分組規則
如果前面使用了分組并分配了組號,在后面可以使用反向引用來使用前面某個組的規則,如果沒有指定分組名,那么默認組號名從1開始自增
匹配模式:
忽略大小寫模式 i
多行模式 m
對每一行進行一次匹配 ,返回多條匹配。 區別于跨行匹配,跨行是把多行視為一個整體匹配一次
點號通配模式 s
默認元字符點號是不能匹配換行符的,加上這個模式就可以匹配任意字符包括換行符了
懶惰模式 U
盡可能少的匹配 acbaab a.*b 使用懶惰模式匹配 acb 否則匹配acbaab
結尾限制 D
abc$ 匹配abc結尾的行,如果行末有換行符會忽略不計,如果使用D模式 ,那么只能以abc結尾,結尾處不能有換行符,否則不能匹配
支持utf8轉義表達 U
php中有兩套正則函數 PCRE POSIX
PHP推薦使用PCRE
- preg_filter — 執行一個正則表達式搜索和替換
- preg_grep — 返回匹配模式的數組條目
- preg_last_error — 返回最后一個PCRE正則執行產生的錯誤代碼
- preg_match_all — 執行一個全局正則表達式匹配
- preg_match — 執行一個正則表達式匹配
- preg_quote — 轉義正則表達式字符
- preg_replace_callback — 執行一個正則表達式搜索并且使用一個回調進行替換
- preg_replace — 執行一個正則表達式的搜索和替換
- preg_split — 通過一個正則表達式分隔字符串
總結:
正則在很多時候可以快速方便的解決問題,其實所有正則能完成的工作都可以自己寫算法來完成, 正則就是一套寫好的字符串操作函數,
這些都是高級人員寫好的,然后經過無數次的改革和優化,單個算法自然是達到了很高的效率,但是如果你的邏輯不是那么簡單,要寫一段很長很復雜的正則,那么這個效率就不能保證了,這種情況下如果能自己寫一個針對性的函數或許效率會更高,說白了你使用正則就相當與在使用別人提供的API,理論來說這樣的效率要低于自己寫的較底層的函數,前提是你要有比較好的算法能力,so 善用正則
如果你已經決定要使用正則了,那么還有些技巧可以讓你提高效率,比如 (a|b|c) 的效率 低于 [abc] ,前者使用了分支,而后者固定字符個數, 這些都要從算法說起,如果你懂得一些基本的算法, so 善用正則