破解謎一樣的正則表達式,從這9招開始

這是菜鳥學python的第45篇原創文章

閱讀本文大概需要5分鐘

都說正則表達式有點像密碼,有的同學看到就頭疼,感覺迷一樣的。

那是因為你們沒有掌握一些基本的要領,今天我們會講9種常見的正則表達式的招式,(有同學會問這麼多招,哪能記得住)

想要練成御劍飛行,基本功必須要紮實.這些都是最最基本的,哪怕死記硬背也要背住(其實2-3遍就能記住,真的不難)

插一句:

有一點要注意Python的字元串本身也用轉義,所以要特別注意,一般我們都建議使用Python的r前綴,就不用考慮轉義的問題了

1.行的起始

先說一個簡單的例子:匹配以cat開頭的

patt=re.compile(r^cat)

表示匹配以c作為一行的第一個字元,後面跟著a,後面跟著t

所以vocative就不會被匹配到,原因是因為cat在字元的裡面

2.行的結尾如何我們要是以某一個字元串結尾的,比如我們要查郵件是以

BR或者Bestregards結尾的,如何匹配:我們用美元符號$來處理

import rensentence=Hi Jack:nn Python is a beautiful languagenn BRnpatt=re.compile(r(BR|Bestregards)$)nm=re.search(patt,sentence)nif m :n print matchnelse:n print not matchn>>nmatchn

$表示匹配的位置是從行的結束的,也就是錨定在行的末尾,然後從行的末尾往前匹配BR或者是Bestregards,所以若你改成下面兩種都匹配不到

sentence=Hi Jack:n

ttPython is a beautiful languagen

ttBRs

sentence=Hi Jack:n

ttPython is a beautiful languagen

ttBestregard

解釋一下:

第一種情況,是把BR改成了BRs,所以匹配不到

第二種情況,是把Bestregards改成了Bestregard,所以也匹配不到

3.單詞的邊界

前面介紹了匹配行的開頭和結尾,那麼如何匹配單詞的邊界呢,簡單正則裡面有2個特殊字元b and B來匹配單詞的邊界 :

  • b 匹配的模式是一個單詞的邊界(不論這個單詞的前面是有字元還是沒有字元)

  • B 匹配出現在一個單詞中間的模式

例如:

the #匹配包含有the的字元串

bthe #匹配任何以the開始的字元串

btheb #僅僅匹配單詞the

Bthe #匹配任意包含the但不以the開頭的單詞

4.字元組

比如我們需要匹配grey或者gray的時候,怎麼辦,可以用正則的[]來表示,gr[ea]y,表示先找到g,然後找到r,然後找到e或者a,最後是一個y

import renword=greynpatt=re.compile(rgr[ea]y)nm=re.match(patt,word)nif m :n print matchnelse:n print not matchn>>nmatchn

若把word改成gray也是匹配的

切記:字元組裡面是匹配一個字元比如H[12345],表示H後面可以跟1或2或3或4或5,而不是12345,千萬不要弄錯了

5.多選結構

我們可以用|來匹配任意子表達式,|是一個非常簡便的元字元,它的意思是"或",通過它我們能把不同的子表達式組合成一個總的表達式,比如am|pm就是能夠同時匹配其中任意一個的正則表達式,回頭再看上面的例子gr[ea]y,其實能寫成grey|gray,或者gr(e|a)y

6.可選項元素

比如6月4號,這個6月可能寫成June也可以寫成Jun,而且日期也有可能寫作fourth或者4th或者4,我們可以寫成(June|Jun)(fourth|4th|4),但是有沒有其他辦法呢,可以用問號?表示可選項

我們分步來處理:

  • 第一部分:(June|Jun)改為(June?),什麼意思呢

    意思是說?出現在一個e後面,表示e是可選的

  • 第二部分:(fourth|4th|4)改為(fourth|4(th)?),什麼意思呢

    意思是說?出現在一個括弧後面,表示這個括弧內的內容是可選的

最後這個複雜的(June|Jun)(fourth|4th|4)就可以變成了June?(fourth|4(th)?),大家看懂了嗎~~有點暈是把,沒事吐吐就習慣了

7.重複出現

重複出現用+和*表示,但是二者有一些小的區別

  • +加號表示:前面緊鄰的元素出現一次或者多次,也就是至少出現一次

  • *星號表示:前面緊鄰的元素出現任意多次,或者不出現.

其實說白了*比+多一種不出現的情況,匹配儘可能多的次數,如果實在匹配不到也不要緊,+也是匹配多次,但連一次匹配都無法完成,就報告失敗

例如:

a* #匹配a,aa,aaa,...還有

a+ #匹配a,aa,aaa,...

解釋一下:

a*表示0個或者多個a,所以為0的時候,就是空字元

a+表示1個或者多個a,所以a至少要有1次

8.匹配重複的次數

1).比如我們想匹配前面的內容重複出現的次數,比如3次,或者是一個區間,比如1-3次,如何匹配:

import rennum_str=123aa45npatt=re.compile(r([1-9]{3}))nm=re.match(patt,num_str)nif m:n print m.group()n>>n123n

表示出現1-9之間的任意一個數字,並且這個數字只能重複出現3次

2).為重複匹配次數設定一個區間

比如美國股票的代碼,都是字元有大寫的也有小寫,基本都是在1到5個字母,如何用正則表達呢

簡單[a-zA-Z]{1,5},就可以來匹配美國股票代碼(1到5個字母)

9.排除型字元組

比如我們想匹配除了1到6以外的任何字元串,怎麼辦,簡單用[^1-6],這個字元組中開頭的^表示"排除的意思".(有同學會舉手說,你剛才不是說^表示開頭嗎,怎麼現在變成排除型了).

這位同學會搶答了,下面就是我要解釋的,正則的複雜性:

  • 當^在字元組的外面的時候"表示一個行的開頭"

  • 當^在字元組的內部(而且是必須緊接著字元組的第一個方括弧之後),它就是一個元字元,表示排除型

比如:找出字母g後面的字母不是u

import renwords=[gold,Google,Sogu,Guess]npatt=re.compile(r.*g[^u])nnfor w in words:n m=re.match(patt,w)n if m:n print wn>>ngoldnGooglen

細心的同學會發現,我們的目的是要"找出字母g後面的字母不是u",為啥Guess不在輸出結果裡面,不是排除型嗎,我先不說答案,大家先思考一下,有興趣的同學可以留言,我會解答.

"歡迎大家關注 菜鳥學Python",更多好玩有趣的Python原創教程,趣味演算法,經驗技巧,行業動態,盡在菜鳥學Python,一起來學python吧

來源 | 菜鳥學python

作者 | xinxin

本文章為微信公眾號「菜鳥學python」獨家原創稿件,未經授權不得轉載

推薦閱讀:

復盤暴走漫畫糾紛,王尼瑪究竟是誰?
在互聯網圈兒——大家都假裝很忙的樣子
有很多人在為Google、臉書吶喊,但曾有人為華為、中興被美國拒之門外而吶喊過嗎?

TAG:互联网 | 编程 | Python |