正則學習(1)--- 基本規則總結

  在正則表達式的使用上,俺一直在打游擊,是時候來個總結了。因爲愚笨等不可抗拒的緣由,只能選簡單的說,只寫下對ASCII編碼字符的匹配和php相關的,其餘的Unicode的和其餘不一樣流派的,之後碰到了再學習下就行,應付日常的應該夠了。php

  首先須要接受正則的概念,它是用來尋找文本的一種規則,簡單的文本檢索,好比字符串查找strpos,只是簡單的查找某一串字符的出現,只要稍微變更下需求,好比要查找這樣5個字符,前面兩個是數字,後面3個是字母,且忽略大小寫,若是單純用字符串查找等方法作,顯得很麻煩,而用正則表達式就無比簡單了。正則很強大很靈活,固然靈活的東西通常規則也有點多。在日常生活中,不知不覺會用到正則相似的東西,好比搜F盤下的全部文本文件:*.txt,或者在某些編輯器如Sublime Text,對正則超找提供了支持,又或者在linux命令中也常常用到:find . -name  '*.log' -print查找當前目錄下擴展名爲log的文件,或者查詢日誌時cat 2015-10-18-log |grep 'show_list'(這個不是,只能說相似):打印出記錄了show_list接口的行等等,以及Apache的RewriteRule對訪問連接的控制,這些都相似或者就是正則表達式的應用。linux

  在php中,用來支持正則的有三種引擎:preg、ereg、mb_ereg,所謂引擎簡單理解就是底層一些對php在進行正則匹配查找時進行支持的庫和接口,不一樣的庫有不一樣的名字,如今用的可能是preg,它在功能和速度上要強於其他二者。preg引擎(或者說套件),即「Perl的正則表達式」(Perl Regular Expression),源於某大牛對當時的ereg套件在性能上的不滿,想作一個更好的庫,因而查閱Perl處理正則的源代碼,可是在他以前另一大牛,也遇到過這個問題,此大牛(後者)研究了一下Perl正則源代碼,以爲繁瑣複雜,因而本身寫了一套兼容Perl的正則庫PCRE(Perl Compatible Regular Expression),編寫清晰,效率出衆,文檔完備,而後前一位大牛將其改寫到php中,就成了preg,一直慢慢改進到今天。因此preg兼容PCRE,PCRE兼容Perl的正則,preg就是Perl正則的親戚,以上爲歷史。正則表達式

  一個簡單的正則表達式示例:'/abc/',表示匹配一個字符串中的abc三個字符,徹底等價於普通的字符串查找方法,正則就是一個字符串,只是特殊的符號有特殊的含義而已,而通常將這串表示正則的字符串稱爲:模式(pattern)。編程

  1. 定界符數組

  在定義一個正則表達式時,首先要有定界符,表示表達式從這兒開始,到那兒結束,最經常使用的是/,如匹配abc的'/abc/',從a開始,到c結束。在php中,還可用其餘的,好比#、!、{}(左邊用{,右邊用})等,全憑我的習慣。框架

      2. 原子異步

  原子是正則表達式中最基本的單位,細分爲5類,俺將伴隨它的功能來記錄。編程語言

  首先,能夠用最普通的字符做爲原子,如a、B、c、一、二、_等編輯器

    '/9527/'
    '/misson failed/'
    '/PHP_VERSION/'

   一些特殊字符和元字符(metacharacter)也能夠,任何一種符號都能在模式中使用,前提是別跟它本身的表示特殊含義的符號相沖突,前面說過,正則很靈活很強大,強大在於有這些特殊含義符號的輔助(有什麼特殊做用後面再說),若是正則中要匹配這個在這裏有特殊含義的符號,須要轉義(escape),很好理解,就跟雙引號字符串中有雙引號也要轉義同樣。這些特殊符號包括.、*、?、+、‘、"、\ 、/ 等等,其實單引號、雙引號有時沒必要轉,全看你寫的表達式用的是單引號字符串仍是雙引號字符串,在php中爲避免出錯寫正則通常用單引號字符串。還有就是別跟本身的定界符衝突,不然系統覺得表達式提早結束而出錯。函數

    '/a\.b\?c\+/'
    '/ab\/123/'

   非打印字符做原子,非打印字符泛指空白字符,即空格、水平製表符\t、垂直製表符\v、回車符\r、換行符\n等,注意此處易埋bug,php用單引號字符串,減小出錯

    '/\r\n/'

  前面說過,能夠匹配通常的單個字符,如9527,9後面接着一個5,再接着一個2,而後是7,如今匹配的並不限於這幾個數字,好比我要匹配兩個數字,只要是數字就行,對於這種帶有通用性質的字符,正則也有表示某一類字符的的表示形式,好比表示數字用\d,表示一個0到9的十進制數字,而\D(大寫形式)表示非十進制數字,\w表示匹配一個單詞,在php的正則流派裏邊,單詞的定義是大寫字母A-Z,小寫字母a-z,數字0-9以及下劃線_,相應的\W大寫形式表示相反的意義。

    '/\d\d/'     // 匹配兩個數字
    '/\D/'       // 匹配一個除數字以外的任意字符
    '/\w/'       // 匹配一個詞
    '/\W/'       // 匹配一個除了詞的任意字符
    '/\s/'       // 匹配一個空白字符
    '/\S/'       // 匹配一個非空白字符

   3.元字符

  元字符就是有特殊意義的字符,如*、+、?、. 、|、^、$等,通常不能單獨出現,只有在修飾它前面的一個(或一些)原子時才表現出它本身的特殊含義,也就是說,它要配合上面說的原子使用纔有意義。它有特殊意義,但就是要匹配它時,就得使用轉義符\了,轉爲普通字符。

  ?:量詞,有或者沒有

      如今要匹配一個單詞意思顏色,有兩種寫法,colour或color,中間的u要麼有1個,要麼沒有,元字符?就適合,並且,若是沒有加括號限制,元字符量詞這類元字符只對位於它前面一個原子起做用,這裏?只做用於u

    '/colou?r/'

  +:量詞,一個或多個

  好比匹配一個或多個數字,注意元字符修飾的原子有多是個序列,但未加括號限制只對一個有效

    '/\d+/'

  *:量詞,0個、1個或多個,即任意數量

    '/\d*/'

  區間:規定重複出現次數

  前面的次數限制畢竟比較死板,來個活的,區間用一對{}表示,{n}表示出現n次,{n,}表示大於或等於n次,{m,n}表示至少出現m次,至多出現n次,最好m小於n,別故意爲難系統~

    '/auth{0,1}/'    // 出現0次到1次,即?
    '/auth{1,}/'     // 至少出現1次,即+
    '/auth{3}/'      // h要出現3次

   匹配任意字符

  .,點號,匹配任意字符,在php中,默認狀況下除了換行符,它能夠匹配任意任意一一個字符,另一種狀況下,它就真的匹配任意字符,包括換行符,後面再說。

  多選結構

  |,表示或,依靠它能夠生成一個多選分支,須要注意的是|在正則中優先級最低,,下面的不是|做用的不是左右的r和c,而是|左右的子表達式,哪怕把一個表達式寫成'/\d+\s*abc{2,5}|ack?\d/',它仍做用於它前面和後面的子表達式\d+\s*abc{2,5}和ack?\d,只要沒有加括號限制

    '/color|colour/'    // 匹配color或colour

  字符組

  匹配若干字符之一,如今要匹配abc中任一個字符,能夠這樣:[abc],包在一堆中括號裏邊,加入要匹配大寫A到大寫Z任一個字符,能夠這樣:[A-Z],中間一個連字符在字符組裏邊就成了有特殊意義的元字符表示從什麼到什麼,,其餘還有數字[0-9],或者只是數字、字母的部分值:[2-5]、[c-h],有幾個須要注意的地方:

  1. 連字符-只有在字符組內部,且在兩個字符之間才被認爲是有效的元字符,出了字符組跟a同樣是普通字符;

  2. 若是字符組內部確實須要匹配-,最好將它放在字符組內最前面,如[-a-z],匹配小寫字母或-,在php中也能夠將它放在最後,如[c-k-](竟然沒報錯-_-#),但放在最前面仍是最保險;

  3. 對於系統不承認的由-標識的順序字符,對於php會報Compilation failed警告,如[a-9]、[9-0]

  4. 字符組的順序通常爲從小到大,不能[9-0],大小寫通常分開寫[A-Za-z],但在php中,至少俺這個5.5版本能夠大小寫混合寫[A-z],表示匹配從A到Z和a到z的字母,不提倡這樣作,其餘語言流派肯能不支持

    '/C[EFIMT]O/'
    '/[A-Za-z0-9_]/'    // 至關於\w,表示單詞
    '/[a-z]+/'          // 匹配一個或多個小寫字母

  排除型字符組

  前面是匹配任意一個[]內的字符,如今剛好相反,不匹配任意一個字符[]內的字符,如[^a-z]:不匹配任意一個小寫字母,在字符組內最前面加^表示取反。一個有意思的例子:

    '/abc[^ABC]/'
    字符串1: 'abcK'
    字符串2: 'abc'       // 匹配?

  字符串1很顯然,字符串2匹配嗎?注意字符組:它匹配未出現的字符。這裏abc後面要跟一個除A、B或C的字符,可是不能沒有,這即是字符組的坑。

  單詞邊界

  有時爲了匹配一個完整單詞,通常單詞給人印象是左右帶有空格,專門有一個表示單詞的這種邊界元字符\b,注意它並不匹配一個空格,而是一個位置,因此單獨的'abc'也被看做一個單詞,雖然它左右並無空格,關於匹配位置後面再詳說。可是正則中,至少目前對單詞的定義還沒那麼強大,就是大小寫字母、數字加下劃線,跟單詞邊界相反的就是\B,只要不是單詞邊界都能匹配

     '/\b\w+\b/'      // 匹配一個單詞
     'hello world'    // 匹配hello(只匹配一次的話)
     'abc'            // 匹配abc

   括號限定

  括號的第一個強大功能,是限定元字符的做用範圍,將表達式分紅一個個子表達式,如'/col(ou)?r/',加了括號後,?元字符做用的對象是ou而再也不只是u,'/abc|def/'指的是匹配abc或者def,但a(bc|de)f匹配的是abcf或者adef,相似編程語言括號運算符,括號內是一個小的單元,至關於一個大原子,固然它還有一個重要做用:分組,後面再說。

  行的開頭與結尾

  每一行字符串都有一個開頭和結尾,開頭和結尾指一個位置,雖然咱們在描述一串字符串會說以...結尾,但正則中不指具體字符,匹配的是位置。好比'/^a.+/',匹配以a開頭的字符串,^表示開頭,$表示結尾,下面是幾個值得注意的例子

    '/^/'                 // 匹配一個行開頭,只要是一行字符串都有開頭,哪怕空字符串,無實際意義
    '/^$/'                // 匹配一個行開頭,緊接着是行結尾,即匹配一個空行
    '/^hello$/'           // 匹配以hello開頭的字符串,隨後改行便結尾,即匹配只有hello字符串的行,該行再無其餘字符
    '/^hello.*hello$/'    // 匹配一個行開頭,接着是hello,接着多是若干其餘字符,而後是hello,緊接着是行結尾,即匹配一個一hello開頭,hello結尾,中間有若干字符的字符串

   注意在默認狀況下,脫字符^和美圓符號$表示匹配一個字符串的開頭和結尾,好比"hello",結尾在緊挨着o的右邊,那麼"hello\nabc"(在php的雙引號字符串中,\n是元序列,表示換行符,但php的單引號字符串\n只是普通字符,一個\一個n,特此說明)該看作一行仍是兩行呢?答案是,在preg中,默認狀況下,仍被看作一行,它的結尾是緊挨着c的右邊,能夠驗證下

<?php
    $pattern = '/hello$/';    // 以hello結尾
    $subject = "hello\nabc";  // 匹配字符串的結尾,而不是邏輯行的結尾
    preg_match($pattern, $subject, $match);
    echo 'match=><pre>';
    var_dump($match);         // 無匹配內容

  咱們把"abc\n"稱爲一個邏輯行,把"abc\ndef\n"稱爲有兩個邏輯行,由於邏輯上它是有兩行字符串的,但preg默認不匹配多個邏輯行(多是坑),管你幾個換行符就當一行字符串看,$直接匹配到這個字符串最後一個位置。那麼php的正則能不能匹配多個邏輯行呢?固然行,要用到模式修飾符,後面再說。

  除了以^表示行開頭,$表示行結尾,在preg中,\A也表示開頭,\z和\Z都表示結尾,不一樣的是\Z能匹配到最後的換行符,而\z不行。

  3. 分組和捕獲

  一個簡單的例子,匹配以單引號或雙引號開頭的字符串,結尾須要是對應的雙引號或單引號(中間不存在轉義過的雙引號或單引號)

    '/["\'].*["\']/'

  若是是上面那樣,第一個字符組匹配了雙引號,是沒法保證第二個字符組匹配相同的雙引號,即如今的要求是,前面那個字符組匹配了什麼,後面那個字符組也須要匹配相同的字符,不是給一個相同的正則表達式就行。

  前面說過括號的第一大做用,限定某些元字符的做用範圍,括號的另外一大做用就是分組捕獲,這是正則的特性。好比'/ab(cd)ef(gh)ij/',有兩個括號,preg引擎會對每一個括號中匹配到的文本進行記錄,以左括號由左往右數,以數字編號,\1記錄的是第一個左括號所在的裏邊的內容,\2記錄第二個左括號所在的裏邊的內容,第n個左括號對應\n,preg最多可記錄4096個(強大!),這裏\1對應cd,\2對應gh。括號起到了分組的做用,而相似\一、\2...\n稱爲反向引用。注意:引用的是正則匹配到的文本,而不是引用的正則表達式

    $pattern = '/(\w)(\d)(.*)/';    // 匹配一個詞,一個十進制數字和若干任意字符
    $subject = 'a57h';
    preg_match($pattern, $subject, $match);
    echo 'match=><pre>';
    var_dump($match);

  結果:

  preg_match方法將捕獲的文本放在$match參數中,數組索引的一、二、3對應的元素分別是捕獲到的\一、\二、\3三個分組文本(索引0列出的是整個表達式匹配到的文本)。

  對於括號嵌套的,只看左括號的相對順序,好比'/(abc(def)g(hij))(k)/',有效的左括號爲4個,\1對應abc的左括號整個括起來的內容(abcdefghij),也包括裏邊嵌套括號匹配的內容,\2對應def,\3對應hij,\4對應k。

   因此對於上邊引號對應的例子能夠是這樣的:'/(["\'].*)\1/',後面的字符要與第一個匹配到的文本一致(注意不是模式一致)。

   可是新的變種又來了,有的想分組捕獲,但有的只想分個組,限定下範圍,不想捕獲,?:來了,(?: ... ),在分組的括號最前面添加問號冒號,就表示取消文本捕獲。所以對於'/(?:abc(de)fg(?:hij))/',\1捕獲的是de,沒有\2。

  除了數字捕獲(\後面跟數字來標識捕獲內容),還可以使用命名捕獲,即給捕獲到的文本取名字,用法(?P<name>...),對括號添加?P<name>,name是取的名字,有的書上寫着(?P=name),5.5親測不行。

    $pattern = '/\w(?P<key1>\w\w)\s+(?P<key2>\d+)/';
    $subject = 'abcd 233';
    preg_match($pattern, $subject, $match);
    echo 'match=><pre>';
    var_dump($match);

  結果:

  在php的命名捕獲時,把原來數字形式的捕獲也記錄了,key1與\1對應,key2與\2對應,反正多一種不嫌多。

  捕獲的另外一個巨大的用處,就是在替換操做時,對匹配的文本的引用,好比如今有表達式 '/123(\d\d\d)ok([a-z][a-z])end/',括號捕獲到三個數字和兩個小寫字母,咱們想提取出來,怎麼辦,就preg來講,使用簡單的替換方法:preg_replace。一個例子

    $pattern = '/123(\d\d\d)ok([a-z][a-z])end/';
    $subject = '123233okhiend';
    $replacement = '$1---$2';    // 在替換字符串中,對捕獲到文本的引用
    $ret = preg_replace($pattern, $replacement, $subject);
    echo 'ret=><pre>';
    var_dump($ret);

  括號捕捉到了233和hi,若是是反向引用咱們知道是\1和\2,替換的字符串$replacement中,使用$一、$2來捕捉它,注意\一、\2是用在原始的正則表達式中的,這裏是替換字符串中,固然,替換操做的是字符串的副本。

  結果:

  若是用命名捕獲來操做,使用對應的$name來引用,親測貌似不行,估計是怕跟上下文中的變量相沖突,可是上面說了,在命名捕獲時,數字索引仍然是有效的,因此在命名捕獲時,咱們仍然能夠再替換字符串中經過$1來引用匹配到的文本。

  一個須要注意的問題:假設我捕獲到了第1組,替換文本是'$15',1後邊又跟着個數字,容易出錯,爲提升解析效率,可以使用{}將數字括起來,如'${1}5',另,這對命名捕獲仍無效。

   4. 環視

  前面的行開頭、結尾是對位置的匹配,環視( lookaround)也是對位置的匹配,對於這種位置匹配,可能一個更熟悉的名字是:零寬斷言。^、$、\A、\Z、\b、\B都算零寬斷言,包括環視結構,固然行開頭和結尾也多稱爲錨點。好比俺曾作的一個小項目中,有這樣的需求,使用一個別人搭建的框架,每個model類處理一張表,表名根據model類的類名肯定,它的類名通常是這樣的class externalLinks extends Model{...},子類名是這樣externalLinks,它的表名是gw_external_links,gw_不說,從externalLinks到external_links須要在左邊是小寫字母,右邊是大寫字母的地方插一個_,再轉小寫,並且類名不必定只有這樣的,好比abcDefGhi,多是3個大小寫單詞,個數不肯定,用字符串的替換顯得比較麻煩,由於個數不肯定,用正則垂手可得就解決了。凡是這種某地方的左邊是啥,右邊是啥,明顯的位置要求的,均可以用環視試一下。環視分爲四種:

  確定順序環視:(?=...),匹配某個位置,它的右邊是...

  確定逆序環視:(?<=...),匹配某個位置,它的左邊是...

  否認順序環視:(?!...),匹配某個位置,它的右邊不是...

  否認逆序環視:(?<!...),匹配某個位置,它的左邊不是...

  不看...就是環視的符號定義,順序、逆序的區別在於一個從左往右看,一個從右往左看。環視在位置檢測時很是有用。例如如今要匹配abc,它的右邊必須是數字,能夠這樣

    '/abc(?=\d)/'

  說說俺本身上面那個問題,找到左邊是小寫字母,右邊是大寫字母的位置,能夠這樣

    '/(?=[A-Z])(?<=[a-z])/'

  若是左右兩邊都須要檢測的,像這種,順序環視跟逆序環視的左右順序的順序不用管,哪一個放左邊哪一個放右邊都行(等價於'/(?<=[a-z])(?=[A-Z])/')。通常來講逆序環視放左邊,順序環視放右邊,一個好習慣是以位置爲中心,想象這個位置左邊應該有什麼,右邊應該有什麼。上面的模式找到位置了用_替換(實際是插入)掉問題基本就解決了。再好比

    $pattern = '/\w+(?=\d)/';
    $subject = 'abcd 233';
    preg_match($pattern, $subject, $match);
    echo 'match=><pre>';
    var_dump($match);

  結果:

  想一想爲啥?匹配一個或多個詞,它的右邊必須是數字,只有'23'符合,它的右邊剛好爲數字,2的前面是空格,不屬於\w範圍,而'233'的後面啥都沒有。

  注意:只匹配位置,不匹配實際文本,這個有時在屢次匹配時有很大區別。

  對於單詞邊界符\b,也可用環視寫出來,單詞的開始邊界是左邊非單詞右邊爲單詞:(?<!\w)(?=\w),單詞的結束邊界是左邊爲單詞右邊非單詞:(?<=\w)(?!\w),合在一塊兒就是:(?<!\w)(?=\w)|(?<=\w)(?!\w)(|,或的左右表達式是總體,它的優先級最低)。

  5. 佔有優先 vs 忽略優先

  標準量詞都是匹配優先的,如*、+、?以及區間量詞{m,n},它們老是在本身的範圍內儘量多的匹配字符,對於{m,n}(m<n)有n個的話毫不止匹配m個就完事兒。例如

    $pattern = '/\w+(?=\d)/';
    $subject = 'hello123';
    preg_match($pattern, $subject, $match);
    echo 'match=><pre>';
    var_dump($match);

  結果:

  上例在匹配單詞時老是儘量匹配最多,因此單看\w+會一直匹配到字符串結尾3處,但隨後的環視檢查出現右邊不是一個數字(什麼都沒有),因而交還一個詞,再看看右邊是否是數字,這下是了(hello12)而後就匹配成功返回,這裏有一個回溯的過程(下一篇寫寫),不細糾結,有的書稱這種匹配優先爲貪婪模式,即標準量詞默認都是貪婪的,儘量多的去匹配的,那麼與之對應的就有非貪婪模式。

  在量詞後面加個問好,表示非貪婪模式,即忽略優先,如*?、+?、??、{m,n}?,非貪婪模式下的量詞老是儘量匹配少的字符,仍是上面那個例子,若是把$pattern改成下面呢?

    $pattern = '/\w+?(?=\d)/';    // 忽略優先

  匹配的結果是'hello',過程是首先+?使得\w每匹配一個詞就檢查下右邊是否是數字,是的話匹配就此中止,返回結果,要保證匹配到的字符最好嘛,不是的話繼續匹配,直到右邊是數字便當即中止返回。忽略優先能夠提早返回結果,固然可能不是最優的,提升匹配速度(下一篇再總結下)。

  有木有倔強的不交還的列?固然有,這就是佔有優先,它在標準量詞後面加一個+,如*+、++、?+、{m,n}+,把上面的例子再改改,有意向不到的結果-_-#

    $pattern = '/\w++(?=\d)/';    // 佔有優先

  記住佔有優先的特色:不交還!\w+一直匹配到hello123結尾,發現以後啥都沒有,失望至極,而後中止匹配,報告匹配失敗了,沒錯此次竟然是匹配失敗了!佔有優先仍屬於匹配優先,儘量多的去匹配,只是匹配到最後若是發現某條件不符,很差意思,他不服,直接中止。因此佔有優先能夠提早報告失敗,提升匹配速度

  忽略下佔有優先的脾氣,來看一個新東西:固化分組。表示方式:(?>...)(它應該屬於分組捕獲的,俺以爲放這兒更好),同佔有優先功能同樣,它也是優先匹配,而且不交還。因此再把上面的$pattern改成這個樣子,也是匹配失敗滴。

    $pattern = '/(?>\w+)(?=\d)/';    // 固化分組

  6. 模式修飾符

  模式修飾符(pattern modifier),放在模式的最後面,結束定界符以後,如'/....../imx',i、m、x表示不一樣的修飾符,能夠一次使用多個。模式修飾符是對正則表達式總體效果起一個調節做用。

  i:匹配時不區分大小寫,如'/abc/i',對匹配到的abc任一個大小寫均可;

  m:將字符串視爲多個邏輯行,還記得前面說匹配一行字符串的開頭^和結尾$嗎?默認preg將字符串視爲一行,哪怕裏邊有有效的換行符,若是加了修飾符m,將帶匹配字符串按照換行符分行,這些行稱爲邏輯行,^匹配每個邏輯行的開頭,$匹配每個邏輯行的結尾;

  s:還記得前面說的匹配任一字符的元字符 . (點號)嗎?preg默認狀況下點號匹配任一個字符,除了換行符,那麼加了s修飾符,點號就連換行符也不拒絕了;

  x:這個修飾符對於複雜的正則表達式很是有用,由於它能夠在正則中添加註釋!!!並且它會忽略正則中的空白符,固然,也包括換行,爲了說明亂舉一例:

    // 使用x修飾符
    $pattern = '/(\w+ \d)
    (?:                 # 這裏匹配啥啥啥
        "\w" | "\d"
        |               # 這裏應當這麼理解那啥
        [-A-Z]+         # 這裏你本身猜
    )/x';
    $subject = 'wcwieu2832z28';
    preg_match($pattern, $subject, $match);

  e:它在特定的地方有用,即preg_replace方法中,preg的preg_replace方法原型以下

    mixed preg_replace(mixed $pattern, mixed $replacement, mixed $subject [, int $limit = -1 [,int &$count ]])

  第二個參數$replacement,會將匹配到文本替換爲它,使用e修飾符,$replacement不只能夠用簡單的文本,不只能夠對捕獲到的文本進行$1式的引用,更流弊的是,能夠寫php代碼,以字符串的形式(有點eval的感受),例

    $ret = preg_replace('/\d([A-Z]+)/e', 'strtolower("$1")', '5BBC');
    echo 'ret=><pre>';
    var_dump($ret);

  但是當俺準備看結果時,報錯:The /e modifier is deprecated, use preg_replace_callback instead,納尼!模式符e被棄用了,讓用preg_replace_callback這個方法,它使用一個會調函數(異步調用)來處理匹配到的結果,顯然比把代碼直接堆在字符串裏好多了,具體怎麼用能夠參考手冊。

   D:設定了此修飾符的話,模式中的$只會匹配字符串的結尾(EOS,End Of String),而不是EOS前面的換行符,即不會看作多行。但若是設定了m修飾符將忽略此選項;

   U:反轉了 * 跟 *? 的含義,原來的匹配優先變爲忽略優先,原來的忽略優先變爲匹配優先。除了讓人更加暈菜之外,好像沒個鳥用。

  最後,還有個文本模式,不是模式修飾符,表示方式 \Q ... \E。

  假如咱們就是想匹配一段文本,可是裏面夾雜了不少元字符,轉義後看起來會很亂。就可使用 '/\Q$*.?|/\E/',只是舉個極端的例子,\Q與\E之間的字符,preg一概把它當作普通字符處理,免去轉義之勞。固然也能夠手動轉義,更加能夠用preg_quote來將這個沒有帶\Q和\E的表達式轉爲一個轉義後的表達式。

  以上,還有些強大的東西,如正則表達式遞歸,暫時用不着。

  之後忘了再來看一眼 >>>逃

相關文章
相關標籤/搜索