乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      如何教你看懂復(fù)雜的正則表達(dá)式

       昵稱14945998 2019-02-28

      【前言】

      1.此文針對,正則表達(dá)式的初學(xué)者,老鳥請飄過。

      正則表達(dá)式的初學(xué)者,常遇到的情況是,對于相對復(fù)雜一點(diǎn)的正則表達(dá)式,覺得很難理解,很難看懂。

      2.此文目的,之前你看不懂,看了此教程后,就基本掌握了,看懂復(fù)雜正則表達(dá)式的思路。

      這樣就可以通過自己的能力,一點(diǎn)點(diǎn)把復(fù)雜的正則表達(dá)式,一點(diǎn)點(diǎn)拆分,一點(diǎn)點(diǎn)分析,知道完全理解。

      3.在看此文之前,肯定需要你本身對于正則表達(dá)式,已經(jīng)有了一些基本的基礎(chǔ),

      比如知道點(diǎn)’.’表示任意字符,星號’*’表示0或多個之類的含義,這樣才有看此文的基礎(chǔ)。

      關(guān)于正則表達(dá)式方面的教程和資料,需要的可以去看我整理的一些資料:

      正則表達(dá)式學(xué)習(xí)心得

      【教程】詳解Python正則表達(dá)式

      【總結(jié)】關(guān)于(C#和Python中的)正則表達(dá)式

      java中的正則表達(dá)式:java.util.regex

      【如何看懂復(fù)雜的正則表達(dá)式】

      基本思路:拆分->各個擊破

      解釋:

      先將一個,很長的,很復(fù)雜的正則表達(dá)式,從左向右,一點(diǎn)點(diǎn)讀取,分析,一點(diǎn)找到某部分的內(nèi)容,是一個邏輯概念上的獨(dú)立的一塊,就暫時拆分出來,如此,一點(diǎn)點(diǎn)把復(fù)雜的正則表達(dá)式,拆分成很多個邏輯上獨(dú)立的小塊,

      然后針對每個小塊的表達(dá)式,再去分析其含義

      每個小塊的正則表達(dá)式都搞懂后

      把和所有的含義,合并出一個整體的含義

      最后就可以實現(xiàn),用人類的語言,把對應(yīng)的復(fù)雜的正則表達(dá)式,一點(diǎn)點(diǎn)解釋出來了,即:

      把,之前看不懂的,復(fù)雜的正則表達(dá)式,翻譯成,人類可以看懂讀懂的語言(至少先讓你自己讀懂看懂)

      在舉例分析之前,需要知道一些前提:

      1.任何復(fù)雜的正則表達(dá)式,都是由寫正則表達(dá)式的人,從簡單到復(fù)雜一點(diǎn)點(diǎn)寫出來的。

      所以,理論上,如何讀懂復(fù)雜的正則表達(dá)式,也就是一個反向解析的過程,即將復(fù)雜的拆分成多個簡單的,功能上,邏輯是獨(dú)立的子表達(dá)式,然后再去分析其含義,最終再合并出來整體的,復(fù)雜的含義。

      2.正則表達(dá)式,即使各種語言的正則表達(dá)式的庫函數(shù),去解析的時候,也是從左到右,一點(diǎn)點(diǎn)分析,一點(diǎn)點(diǎn)拆分,將復(fù)雜的差分成多個子表達(dá)式,以實現(xiàn),計算機(jī)語言內(nèi)部,去理解此表達(dá)式的。

      此處,只是通過人類的方式,手動從左到右,一點(diǎn)點(diǎn)分析而已,也算是和計算機(jī)語言識別正則的類似的過程。

      3.雖然正則表達(dá)式,不同的語言,具體的寫法,有些略微的差別,但是本質(zhì)上的,絕大部分的正則表達(dá)式的寫法,都是基本類似的。

      【舉例說明,如何實現(xiàn)拆分復(fù)雜的正則表達(dá)式】

      舉例:

      /^[A-Z]:\\{1,2}[^/:\*\?<>\|]+\.(jpg|gif|png|bmp)$/i正則表達(dá)式表示什么意思?

      首先,對于拿到這個,看似很繁瑣的字符串:

      /^[A-Z]:\\{1,2}[^/:\*\?<>\|]+\.(jpg|gif|png|bmp)$/i

      作為,相對比你熟悉正則的我,一看就知道,是PHP或Perl一類的語言中的正則表達(dá)式,因為這里是:

      /xxx/i

      的格式,其中xxx表示真正的正則表達(dá)式本身,而后面的i表示ignoreCase,即忽略大小寫的意思。

      而如果你只是熟悉其他如Python等語言的正則表達(dá)式,則此處無需太關(guān)心那兩個斜杠,可以將其理解為,類似于Python中的這樣的寫法:

      re.match("xxx", re.I)

      其中的xxx,是此處真正的正則表達(dá)式:

      ^[A-Z]:\\{1,2}[^/:\*\?<>\|]+\.(jpg|gif|png|bmp)$

      而re.I即re.IGNORECASE,表示忽略大小寫的意思。

      接下來,就來分析此處的xxx,即:

      ^[A-Z]:\\{1,2}[^/:\*\?<>\|]+\.(jpg|gif|png|bmp)$

      的完整的含義:

      對于我來說,看到此正則表達(dá)式:

      ^[A-Z]:\\{1,2}[^/:\*\?<>\|]+\.(jpg|gif|png|bmp)$

      后,我可以直接將其,按照之前所介紹的方法,直接拆分出對應(yīng),幾個子表達(dá)式,其中每個子表達(dá)式,相對來說,是邏輯上獨(dú)立的,或者是沒關(guān)系,關(guān)系不大的各個小的正則表達(dá)式。

      先說拆分的結(jié)果如下:

      1^
      2[A-Z]
      3:
      4\\{1,2}
      5[^/:\*\?<>\|]+
      6\.
      7(jpg|gif|png|bmp)
      8$

      但是,作為讀者的你,肯定看了會說,我怎么才能,像我這里一樣,一次性就看出,如何將上述復(fù)雜的正則表達(dá)式,一下次分出這8部分,即(將上面那個復(fù)雜的正則表達(dá)式)大卸八塊呢?^_^

      那么此處,就來介紹一下,基本的思路,或者說,我是怎么實現(xiàn)此過程的:

      【如何拆分正則表達(dá)式: ^[A-Z]:\\{1,2}[^/:\*\?<>\|]+\.(jpg|gif|png|bmp)$】

      首先,看到這么一堆的復(fù)雜的字符,其實我也不可能立刻實現(xiàn),全部拆分出來。

      我也是一點(diǎn)點(diǎn),像之前介紹的方法和思路一樣,是從左到右,一點(diǎn)點(diǎn)去,識別,區(qū)分,然后一點(diǎn)點(diǎn)分出來這么多個子表達(dá)式,子部分的:

      1.比如,首先,我從左往右看的話,第一個看到的是’^’,對此,對于有了正則表達(dá)式最最基礎(chǔ)的你,應(yīng)該知道,這個是匹配字符串的開始的;

      而很明顯,對于’^’,此處,一般不會,此處也沒有后面有啥限定符,即沒有和其他字符,去搭配使用。

      所以,此’^’,就是我們所拆分出來的,第一個,相對邏輯上獨(dú)立的,子正則表達(dá)式,所以就可以寫出第一個小子表達(dá)式了:

      1^

      2.然后接著來分析,接下來是左中括號'[',而對于左中括號,還是那句話,作為已有正則表達(dá)式的基礎(chǔ)的你,知道其,一般來說都是和另外一個右中括號’]’去搭配使用,并且左右中括號里面,也會有一些字符,以表示中括號內(nèi)的字符,所組成的集合,即類似于[xxx]的形式,對此,接著往后看,可以說,此處還是很簡單的,就看到了后面還有’A-Z]’,正好和'['組成了'[A-Z]’,正好符合我們所理解和期望的[xxx]的形式。

      而此處,很明顯,就是A-Z,對應(yīng)著正則表達(dá)式的語法,在中括號內(nèi),可以通過短橫線鏈接起始字符,表示一段范圍內(nèi)的字符,此處即通過A-Z表示,A,B,C,。。。,X,Y,Z,這26個大寫字母。

      所以,此處,看似,也就很清楚了,覺得第二個子正則表達(dá)式,就是[A-Z]了。

      而作為比你經(jīng)驗稍多的我,要告訴你,其實你此處這樣的想法,是嚴(yán)謹(jǐn)?shù)?,因為,對于,中括號?nèi)部表示字符集合,[xxx]的寫法,往往后面還會跟著一些限定符,去表示此集合字符的個數(shù)方面的限定,比如加號’+’表示去匹配,往后數(shù),盡可能多個,比如表示最少2個,最多5個的'{2,5}’等等。

      而此處呢,算是巧了,后面實際上,是沒有這類限定符的,因為我們看到了,后面只有冒號’:’,而冒號,此處,正如按照正常邏輯所理解的一樣,就是表示匹配冒號字符’:’本身而已。

      所以,此處,由于巧了,后面沒有字符個數(shù)方面的限定符,所以,第二個子正則表達(dá)式,正好就是[A-Z]本身而已,所以,接著寫出,我們已經(jīng)拆分出來的,共兩個子正則表達(dá)式了:

      1^
      2[A-Z]

      3.上面已經(jīng)分析了,此處后面跟著的字符,是冒號這個字符’:’,同理,由于后面沒有看到其他的加號’+’之類的限定符,所以此處,冒號本身,就是表示一個完整的子正則表達(dá)式,去匹配單個的冒號了。

      所以,此處第三個,子正則表達(dá)式也就是此冒號字符本身了。所以,現(xiàn)在共拆分出來三個子正則表達(dá)式了:

      1^
      2[A-Z]
      3:

      4.可以看到,冒號后面是個反斜杠’\’,而看到反斜杠,作為已了解正則表達(dá)式的語法的你,應(yīng)該知道,正則表達(dá)式中,會有很多’\x’其中x是某個字母的形式,而不同的字符,組合出來的,表示不同的各種含義,比如常見的\d表示數(shù)字0-9等等。

      而此處,看到的是反斜杠后面’\’后面,又跟了個反斜杠’\’,對此,根據(jù)正則表達(dá)式的語法,則是表示反斜杠這個字符本身,就是想要去匹配一段字符串中,是否有反斜杠這個字符本身。

      然后接著往后看,是{1,2},很明顯,是之前已提到多次的,限定符,作用是,限制(前面的字符的)個數(shù)是,至少1個,最多2個。所以此處就是去限定前面的,反斜杠字符本身,所以加起來,就是\\{1,2},而對應(yīng)的含義也就是

      去匹配,至少一個反斜杠,最多2個反斜杠。

      所以,目前已拆分出共4個子表達(dá)式了:

      1^
      2[A-Z]
      3:
      4\\{1,2}

      5.再往后面分析,是左中括號'[',根據(jù)正則表達(dá)式的語法,和前面已經(jīng)討論過一次中括號的用法,我們可以知道,后面一定還有一個右中括號,所以,把左右中括號,以及中間內(nèi)容,都一起寫出來,就是:

      [^/:\*\?<>\|]

      但是,對于中括號中間的這么一堆字符:

      ^/:\*\?<>\|

      至少看起來,也還是比較復(fù)雜的。

      再但是呢,對于已經(jīng)了解正則表達(dá)式語法的你,應(yīng)該知道,中括號內(nèi),表示取反的寫法是,對應(yīng)的字符或字符集,在其前面,添加上那個特殊字符,向上的箭頭,此處叫做插入字符’^’,表示針對某個,或某些字符,取反的意思,即匹配除了這些字符之外的那些字符。

      而此處,就是對應(yīng)的

      對于

      /:\*\?<>\|

      前面加上個插入符號’^’,變成:

      ^/:\*\?<>\|

      表示,匹配,除了 字符組合:

      /:\*\?<>\|

      之外的字符。

      而此處的字符組合:

      /:\*\?<>\|

      其實就是一堆的字符,一點(diǎn)點(diǎn)寫出來的,其詳細(xì)含義,我們后續(xù)再分析。

      此處還沒完,因為此處的[^xxx]的形式之后,還有個加號’+’,對應(yīng)含義也很明確,就是前面那種字符,即除了/:\*\?<>\|之外的字符,的個數(shù),此處通過加號去限定為,至少是1個,可以更多個,即>=1的個數(shù)。

      所以,算是[^xxx]+的形式了,其中xxx是/:\*\?<>\|

      因此,此處已經(jīng)共分析出5個子表達(dá)式了:

      1^
      2[A-Z]
      3:
      4\\{1,2}
      5[^/:\*\?<>\|]+

      6.再往后看,就是一個反斜杠’\’加上一個點(diǎn)’.’,即’\.’,其表示點(diǎn)字符本身,這點(diǎn)你也應(yīng)該在學(xué)習(xí)正則表達(dá)式基本語法的時候,有所了解。

      此處再多解釋一句就是,之所以不直接寫點(diǎn)’.’,是因為字符點(diǎn)’.’本身,在正則表達(dá)式中,是匹配任意一個單個字符的意思,而想要匹配這樣的,在正則表達(dá)式中被用于表示的含義的字符的時候,就需要用到反斜杠,反斜杠用來表示所謂的轉(zhuǎn)義。

      在正則表達(dá)式中,常見的就有:

      特殊字符正則表達(dá)式中所代表的特殊含義想要匹配對應(yīng)的字符本身的寫法
      .任意單個字符\.
      ?限定符,表示0或1個\?
      *限定符,0或多個\*
      ( , )左右括號聯(lián)合起來,表示一個group組\( , \)
      [ , ]左右中括號括起來,表示字符集合\[ ,  \]

      因此,此處一共已拆分出6個子正則表達(dá)式了:

      1^
      2[A-Z]
      3:
      4\\{1,2}
      5[^/:\*\?<>\|]+
      6\.

      7.再往后看,后面是一個左括號'(',很明顯,此處后面肯定有一個右括號,和此處的左括號聯(lián)合起來,表示一個組group。

      此處,很簡單,就可以看出來是

      (jpg|gif|png|bmp)

      注:更復(fù)雜的正則表達(dá)式,可能會出現(xiàn)多個group嵌套的情況,即括號內(nèi)嵌套括號的情況,此時,此種拆分方法仍然有效,還是找到最開始的左括號,此時對于括號層次來說肯定是最外層,所匹配的那個的最外層的右括號,那這一部分拿出來,繼續(xù)分析即可。如果存在更多曾的括號嵌套括號,仍然是找到對應(yīng)匹配的括號即可。

      而對于此處的group組:

      (jpg|gif|png|bmp)

      的含義,后面再詳細(xì)分析。

      此時,也已經(jīng)拆分出來,共7個子表達(dá)式了:

      1^
      2[A-Z]
      3:
      4\\{1,2}
      5[^/:\*\?<>\|]+
      6\.
      7(jpg|gif|png|bmp)

      8.最后,還剩下一個美元符號’$’,表示匹配字符串末尾,這個很好理解。不多解釋。

      此時,就已經(jīng)實現(xiàn)了,把上述的一個復(fù)雜的正則表達(dá)式,拆分成多個邏輯上獨(dú)立的,共8個,子正則表達(dá)式了:

      1^
      2[A-Z]
      3:
      4\\{1,2}
      5[^/:\*\?<>\|]+
      6\.
      7(jpg|gif|png|bmp)
      8$

      看到這里,對于如何從左往右看,一點(diǎn)點(diǎn)根據(jù)邏輯組合,去拆分成多個子表達(dá)式,的總體方法和思路,應(yīng)該大概清楚了。

      余下的事情,就是自己通過多讀多看多學(xué)習(xí),去了解別人寫的正則表達(dá)式,用此套分析方法,去拆分了。

      知道了方法,加上盡量多的練習(xí),自然會對正則表達(dá)式,越來越熟悉,越來越理解的。

      此處,對于此正則表達(dá)式的分析,還沒完。因為還有幾個字正則表達(dá)式的含義,沒有完全分析透徹。

      下面先來總結(jié)一下,已經(jīng)知道的,各個子表達(dá)式的含義:

      子正則表達(dá)式序號子正則表達(dá)式內(nèi)容子正則表達(dá)式的含義仍需后續(xù)分析的部分子表達(dá)式
      1^匹配字符串的開始
      2[A-Z]匹配單個字符,此單個字符可能是A-Z中的任何一個
      3:匹配冒號字符’:’本身
      4\\{1,2}匹配反斜杠字符,最少1個,最多2個
      5[^/:\*\?<>\|]+匹配除了 /:\*\?<>\| 之外的其他字符,個數(shù)上則是盡可能多個/:\*\?<>\| 的含義
      6\.匹配字符點(diǎn)’.’本身
      7(jpg|gif|png|bmp)匹配group,group內(nèi)部是jpg|gif|png|bmpjpg|gif|png|bmp 的含義
      8$匹配正則表達(dá)式的末尾

      很明顯,還剩兩個我們沒有分析,下面就來詳細(xì)分析解釋其含義:

      1./:\*\?<>\| 的含義

      其實,理論上,對于這樣的字符串:

      /:\*\?<>\|

      其實也是繼續(xù)將其按照上述方法,去將其拆分為不同的子表達(dá)式。

      只是由于此處看似復(fù)雜,其實還是很簡單,所以,直接分析一下,即可看出其含義。就不詳細(xì)拆分了。

      此處,根據(jù)字符本身含義,依次是:

      /斜杠字符本身
      :冒號字符本身
      \*星號字符’*’本身
      \?問號字符’?’本身
      <小于號字符'<'本身
      >大于號字符’>’本身
      \|豎線字符’|’本身

      所以,此部分

      的總體含義就是:

      字符,斜杠,冒號,星號,問號,小于號,大于號,豎線,這些字符(集合)

      而放到[^xxx]里面,變成:

      [^/:\*\?<>\|]

      的意思就是

      除了字符:

      斜杠,冒號,星號,問號,小于號,大于號,豎線

      這些字符之外的,其他的任意字符

      而再加上之前的加號’+’去限定其個數(shù)是最少1個,>=1個,變成:

      [^/:\*\?<>\|]+

      所表示的意思就很清楚了:

      去匹配 盡可能多個字符,這些字符是:

      除了字符:

      斜杠,冒號,星號,問號,小于號,大于號,豎線

      之外的,其他的任意的字符

      到此,對此

      [^/:\*\?<>\|]+

      的含義,才算基本明確。

      而如果你本身對于windows等操作系統(tǒng)對于文件名或者路徑字符的限制有了解的話,你會發(fā)現(xiàn),這基本上就是

      我們所常見的,對于你在windows中,問文件或文件夾命名時,其所提示的,不允許你名字中包含這類:

      斜杠,冒號,星號,問號,小于號,大于號,豎線

      即:

      /,:,*,?,<,>,|

      而此時,如果你稍微會點(diǎn)舉一反三/觸類旁通的思想的話,就會聯(lián)想到,此處去匹配的東西,很可能是文件或文件夾的名字方面的東西。

      2.jpg|gif|png|bmp 的含義

      此處的正則表達(dá)式,很明顯看出就是:

      xxx|xxx|xxx

      的格式,其中xxx分別是,具有不同可能的字符串,即多個可能性之一

      對應(yīng)的,其所表達(dá)的意思是,去匹配:

      要么是jpg,要么是gif,要么是png,要么是bmp

      (除了這幾種可能外,其他的都不匹配)

      對于這種匹配多種可能性的正則的寫法,想要深入了解的話,可以參考教程:

      【教程】詳解Python正則表達(dá)式之: '|’ vertical bar 豎杠

      所以,此時,我們就可以把每部分的內(nèi)容的含義,都完整分析出來了:

      子正則表達(dá)式序號子正則表達(dá)式內(nèi)容子正則表達(dá)式的含義
      1^匹配字符串的開始
      2[A-Z]匹配單個字符,此單個字符可能是A-Z中的任何一個
      3:匹配冒號字符’:’本身
      4\\{1,2}匹配反斜杠字符,最少1個,最多2個
      5[^/:\*\?<>\|]+匹配 >=1個,但盡可能多的,除了斜杠,冒號,星號,問號,小于號,大于號,豎線之外的其他的任意字符
      6\.匹配字符點(diǎn)’.’本身
      7(jpg|gif|png|bmp)匹配要么是jpg,要么是gif,要么是png,要么是bmp
      8$匹配正則表達(dá)式的末尾

      所以,把這些各個子正則的含義,連接在一起,就可以用語言表示為:

      去匹配一個字符串,

      該字符串,開頭部分,就一個字母,該字母可能是從A到Z的任何一個字母,

      后面跟著一個冒號,

      再后面是1個或2個反斜杠,

      然后是至少一個,但盡量多的,除了斜杠,冒號,星號,問號,小于號,大于號,豎線之外的其他的任意字符,

      然后是字符點(diǎn),

      然后以jpg,gif,png,bmp中的其中一個而結(jié)尾

      而對應(yīng)的,由于之前還有flag標(biāo)志,表示忽略大小寫,則所匹配的內(nèi)容,就是上述內(nèi)容的表述,再加上一個,期間部分大小寫,就可以了。

      所以,最終所要表述的含義就是:

      去匹配一個字符串, 期間字母不分大小寫,

      該字符串,開頭部分,就一個字母,該字母可能是從A到Z的任何一個字母,

      后面跟著一個冒號,

      再后面是1個或2個反斜杠,

      然后是至少一個,但盡量多的,除了斜杠,冒號,星號,問號,小于號,大于號,豎線之外的其他的任意字符,

      然后是字符點(diǎn),

      然后以jpg,gif,png,bmp中的其中一個而結(jié)尾

      由此,我們可以隨便寫出來一個,符合該規(guī)則的字符串,比如:

      a:\123abc.jpg

      a:\\123abc.bmp

      a:\\123abcdef.jpg

      A:\\123abcdef.jpg

      E:\\abc123.png

      等等,諸如此類的字符串。

      此時,已可很明顯看出來其用意了,其就是要去匹配:

      Windows類系統(tǒng)(如XP,Win7等)中,本地的某個磁盤分區(qū)根目錄下的某張圖片而已。

      至此,算是完整的,從開始的,無法用肉眼一眼就看出來含義的,那個復(fù)雜的,正則表達(dá)式,將其一點(diǎn)點(diǎn)拆分,分成多個子表達(dá)式,各個擊破其子表達(dá)式的含義,最終再把每個子表達(dá)式的含義合成在一起,再加上對應(yīng)的flag標(biāo)志的影響,最終生成了復(fù)雜表達(dá)式的最終含義,以及,用文字描述出來,最終,領(lǐng)悟和理解,原始的正則表達(dá)式,所要表示的含義。

      通過此分析過程可見,其實再復(fù)雜的表達(dá)式,也都是可以通過拆分的方法,由繁化簡,而逐個擊破,了解細(xì)節(jié)的含義,再整合出宏觀上的整體的含義,最終搞懂完整的表達(dá)式的含義的。

      只是過程,或繁或簡,取決于表達(dá)式本身的復(fù)雜程度,以及你本身所對正則表達(dá)式的理解和掌握的程度。

      【總結(jié)】

      千言萬語總結(jié)出幾句話:

      1. 對于復(fù)雜的正則表達(dá)式,即使從左往右,一點(diǎn)點(diǎn)分析,拆分出多個子正則表達(dá)式,然后各個擊破,搞懂其含義,最后再合成一個總體的含義,即可實現(xiàn),將復(fù)雜的正則表達(dá)式,翻譯成人類可以讀懂的含義了。

      2.再復(fù)雜的正則表達(dá)式,花足夠的時間去分析,都是能搞懂的。 只不過具體要花多長時間,則因人而異。

      3.想要盡快的,準(zhǔn)確的理解原正則表達(dá)式所要描述的含義,還是要多多練習(xí),最終達(dá)到熟能生巧,以至于觸類旁通的效果。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多