php正則表達式心得總結

1、php採用的是PCRE模式:

http://php.net/manual/zh/book.pcre.php
PCRE模式php


2、經常使用函數

  1. preg_replace
    執行正則表達式替換
    http://php.net/manual/zh/function.preg-replace.php
preg_replace($pattern, $replacement, $string);
  1. preg_match
    執行一次正則表達式匹配
$subject = "abcdef";
$pattern = '/^def/';
preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
print_r($matches);
  1. preg_match_all
    執行一個全局正則表達式匹配
    preg_match()返回 pattern 的匹配次數。 它的值將是0次(不匹配)或1次,由於preg_match()在第一次匹配後 將會中止搜索。preg_match_all()不一樣於此,它會一直搜索subject 直到到達結尾。 若是發生錯誤preg_match()返回 FALSE。

3、模式修飾符(匹配模式)

http://php.net/manual/zh/reference.pcre.pattern.modifiers.phpgit

  • i:大小寫不敏感
  • m:可跨行匹配,默認是不跨行匹配
  • s:點號元字符可匹配換行符,默認點元字符是不匹配換行符
  • U:這個修飾符逆轉了量詞的"貪婪"模式。 使量詞默認爲非貪婪的,經過量詞後緊跟? 的方式可使其成爲貪婪的。這和 perl 是不兼容的。 它一樣可使用 模式內修飾符設置 (?U)進行設置, 或者在量詞後以問號標記其非貪婪(好比.*?)
  • u:模式字符串被認爲是utf-8的,php 4.3.5 開始檢查模式的 utf-8 合法性
  • D:$元字符匹配結果中不包括換行符,默認模式是包括換行符的,設置成上面的m模式時會被忽略
  • x:不經常使用,模式中的沒有通過轉義的或不在字符類中的空白數據字符總會被忽略

4、還有一些函數

  1. preg_replace_callback 執行一個正則表達式搜索而且使用一個回調進行替換
  2. preg_split 正則分割字符串爲數組

5、子組(子模式)

  1. 字符集匹配 若是是字符集是多個字符組成,也叫字組(子模式),好比匹配apple和orange任意一個:
this is a (apple|orange)
//若是要否認子模式,則須要使用斷言:前斷言?!和後斷言?<!
this is a (?!apple|orange).*

會匹配:this a apple、this a orange、this a ,能夠匹配空字符
若是不須要捕獲括符內容的話,在前面加上 ?: 便可,若是須要再加上內部選項設置,在 ?:之間設置,一下寫法做用是相同的github

  1. 字組(子模式)命名 三種寫法,後面兩種須要版本>=php5.2.2支持:
(?P<name>pattern)
(?<name>pattern) 
(?'name'pattern)
  1. 多個子組能夠共用一個後向引用數字
    有個這樣的問題,當咱們這樣用的時候:
    (?:(Sat)ur|(Sun))day
    這裏當後向引用 1 空時Sun 存儲在後向引用 2 中. 當後向引用 2 不存在的時候 Sat 存儲在後向引用 1中; 使用 (?| 修改模式來修復這個問題:
    (?|(Sat)ur|(Sun))day
    使用這個模式, Sun和Sat都會被存儲到後向引用1中。

6、重複/量詞

單字符量詞正則表達式

  • * 等價於 {0,}
  • + 等價於 {1,}
  • ? 等價於 {0,1}

特殊用法數組

  • 量詞緊跟着一個 ?(問號) 標記,它就會成爲懶惰(非貪婪)模式,若是在模式修飾符中設置了U 模式,量詞後面加 ?(問號) 標記則成婪模式,就是和全局的匹配模式模式反着來。
  • 量詞緊跟着一個 +(加號) 標記,它會吃掉整個字符串

7、後向引用

  1. 在大於等於php5.2.2版本中採用 \g{1} 寫法能夠更好的理解,序列\1, \g1,\g{1} 之間是同義詞關係,這種用法能夠消除使用反斜線緊跟數值描述反向引用時候產生的歧義app

  2. \g 轉義序列緊跟一個負數表明一個相對的後向引用。好比: (foo)(bar)\g{-1} 能夠匹配字符串 」foobarbar」, (foo)(bar)\g{1} 能夠匹配 」foobarfoo」。 這在長的模式中做爲一個可選方案, 用來保持對以前一個特定子組的引用的子組序號的追蹤。函數

  3. 後向引用也支持使用子組名稱的語法方式描述, 好比 (?P=name) 或者 PHP 5.2.2 開始能夠實用\k<name> 或 \k'name'。 另外在 PHP 5.2.4 中加入了對\k{name} 和 \g{name} 的支持。性能


8、斷言

  1. 前瞻性斷言:只對它前面的字符生效
  • 正面斷言:以 (?= 開頭
  • 消極斷言:以 (?! 開頭
  1. 後瞻性斷言:只對它後面的字符生效
  • 正面斷言:以 (?<= 開頭
  • 消極斷言:以 (?<! 開頭

9、條件子組

可使匹配器根據一個斷言的結果, 或者以前的一個捕獲子組是否匹配來條件式的匹配一個子組或者在兩個可選子組中選擇。 條件子組的兩種語法以下:ui

(?(condition)yes-pattern)  
(?(condition)yes-pattern|no-pattern)

10、性能

Jeffrey Friedl 書(精通正則表達式)中包含了不少關於正則表達式性能的討論。this

  1. [aeiou] 這樣的字符類會比可選路徑 (a|e|i|o|u) 高效
  2. 模式匹配沒有換行符的目標字符串,^.* 性能更佳
  3. (a+)b 比 (a+) 性能高,(a+)* 模式能夠有 33 種方式匹配 」aaaa」,它會嘗試每種可能的變化,很消耗性能

11、其餘知識點

  1. 字符集匹配
    單個可選分支是這樣寫,好比匹配abc中任意一個:
[abc]

若是是字符集是多個字符組成,也叫字組(子模式),好比匹配apple和orange任意一個:

this is a (apple|orange|)

會匹配:this a apple、this a orange、this a ,能夠匹配空字符
若是不須要捕獲括符內容的話,在前面加上 ?: 便可,若是須要再加上內部選項設置,在 ?:之間設置,一下寫法做用是相同的

(?i:saturday|sunday)
(?:(?i)saturday|sunday)
  1. 關於錨 ^ 元字符
    正常狀況下^表示開頭處,可是在字符集下,它表明反向(否認),好比下面表示不包含abc中任意一個字符
[^abc]
  1. 內部選項設置
    默認的模式修飾符是全局的,但有些場景須要使用局部修飾符(也就說說局部模式修飾符),好比某部分匹配能夠不區分大小寫(默認是嚴格大小寫區分的),使用方法爲:(?修飾符)
apple (?iand) orange

以上會匹配apple and orange、apple And orange等等

參考:http://louiszhai.github.io/2016/06/13/regexp/

相關文章
相關標籤/搜索