python|re模塊分組匹配與匹配對象使用(含實例串講)

本博文源於python基礎,主要探討re模塊的分組匹配與匹配對象使用。

正則概述

正則的原理是《自動機》這門課講的內容。
1986年圖靈獎–約翰·霍普克洛夫特和羅伯特·陶爾揚簡介這門課的創始人就是他們,有興趣點開看看。之前也做過所有圖靈獎大佬合集,也可以看看。正則的原理,我也做了博文。因此,再學正則就會發現很親近。無非就這些元字符的排列組合。python外加封裝罷了。
在這裏插入圖片描述
大家在學習下面的時候,不要慌亂。謹記一條口訣:先看標題講了啥,再看內容有沒有跟之前學過相似。類比學習。

re模塊

re是python正則模塊標準庫

正則匹配搜索函數

這裏有兩個函數作正則匹配,一個是match,另一個是search。當博主去百度搜索的時候,發現match是匹配搜個,search是從全體字符串尋找匹配。而findall是一個查找所有並返回列表,而前面兩個是返回對象。我們先看原型

re.match(pattern,string[,flags])
re.search(pattern,string[,flags])
re.findall(pattern,string[,flags])
  • pattern 正則匹配模式
  • string 要進行匹配的字符串
  • flags 可選參數,進行匹配的標誌.(flags細講)
flag選項 意義
re.I 忽略大小寫
re.L 根據本地設置而更改\w.\W.\b.\B.\s,以及\S的匹配內容
re.M 多行匹配模式
re.S 使"."元字符也匹配換行符
re.U 匹配Unicode字符
re.X 忽略pattern中的空格,並且可以使用“#”

這裏演示一下match和search、findall匹配。打開ipython演示喲!

In [11]: s = 'Life can be good'

In [12]: import re

In [13]: print(re.match('life',s,re.I))
<re.Match object; span=(0, 4), match='Life'>

In [14]: print(re.match('life',s))
None
In [15]: print(re.search('be',s))
<re.Match object; span=(9, 11), match='be'>

In [16]: print(re.findall('[a-z]{1,3}',s))
['ife', 'can', 'be', 'goo', 'd']

In [17]:          

sub()與subn()函數

這兩個函數多了一個n,就當作是附加次數的意思

  • sub返回替換後的字符串
  • subn返回一個元組,元組包括替換後的字符串和一共替換的次數
re.sub(pattern,repl,string[,count])
re.subn(pattern,repl,string[,count])
  • pattern 正規表達式模式
  • repl 要替換成的內容
  • string 進行內容替換的字符串
  • count 可選參數,最大替換次數

In [18]: import re

In [19]: s = 'Life can be bad'

In [20]: print(re.sub('bad|be','good',s,1))
Life can good bad

In [21]: s
Out[21]: 'Life can be bad'

In [22]: print(re.subn('bad|be','good',s,1))
('Life can good bad', 1)

In [23]:

split()函數

想想python本身就有分割。然後正則再來一個分割。其實re.split()函數用於分割字符串,它返回分割後的字符串列表。

re.split(pattern,string[,maxsplit = 0])
  • pattern 正則表達式模式
  • string 要分割的字符串
  • maxsplit 可選參數,最大分割次數
In [23]: s = 'I2like3py4rex5'

In [24]: re.split('\d',s)
Out[24]: ['I', 'like', 'py', 'rex', '']

In [25]:

正則表達式對象

講到這裏大家可以鬆口氣了,這裏不過是給我們廣大程序員一個方便的。它將正則實例化方便我們多次使用。所以官方叫做預編譯,總所周知編譯完成爲可執行程序它的內容就被固定下來,這裏也是同理。讓我們一起體驗一下吧!

compile(pattern[,flags])
  • pattern 正則表達式匹配模式
  • flags 可選參數,編譯標誌

預編譯完畢,是要執行的,執行的有幾個屬性跟上面講過的一致,下面就一起帶過吧

match()

跟上面的match相同,要匹配的字符串位於開始

match(string[,pos[,endpos]])
  • string 要進行匹配的字符串
  • pos 可選參數,進行匹配的起始位置
  • endpos 可選參數,進行匹配的結束位置

search()

跟上面的search類似,全體字符串中查詢

search(string[,pos[,endpos]])
  • string 要進行匹配的字符串
  • pos 可選參數,進行匹配的起始位置
  • endpos 可選參數,進行匹配的結束位置

findall()

findall(string[,pos[,endpos]])

跟上面的findall類似

sub()和subn()

跟上面的sub與subn同理

sub(repl,string[,count=0])
subn(repl,string[,count=0])
  • repl 要替換成的內容
  • string 進行內容替換的字符串
  • count 可選參數,最大替換次數

split()

與上面的split類似

split(string[,maxsplit=0])
  • string 要分割的字符串
  • maxsplit 可選參數,最大分割次數

這裏我們將簡單測試一二

例子:給定一個字符串,以數字切割
  • I1like2python3

In [26]: import re

In [27]: rex = re.compile('\d')

In [28]: s = 'I1like2python3'

In [29]: rex.split(s)
Out[29]: ['I', 'like', 'python', '']

分組匹配與匹配對象使用

知道了前面那麼多,爲什麼還要學習這個?因爲有一些字符串往往有規律,分成組後更容易操作
例如:

  • 郵箱的規則
  • 郵編的規則
  • 號碼的規則等等

分組基礎

python以一對圓括號"()"來表示位於其中的內容屬於一個分組

例子:演示用正則分割號碼的區號和本地號碼


In [41]: import re

In [42]: s = 'Phone No. 010-87654321'

In [43]: r = re.compile(r'(\d+)-(\d+)')

In [44]: m = r.search(s)

In [45]: m
Out[45]: <re.Match object; span=(10, 22), match='010-87654321'>

In [46]: m.groups()
Out[46]: ('010', '87654321')

In [47]:

分組擴展

小朋友頭上是否有很多問號?確實!分組擴展(?<組名>)遍地都是問號

擴展語法 意義
(?Lmsux) 設置匹配標誌,可以是左邊字符以及它們的組合,其含義與編譯標誌相同
(?:…) 匹配但不捕獲該匹配的子表達式
(?P=name) 表示在此之前的名爲name的組
(?#…) 表示註釋
(?=…) 用於正則表達式之後,表示如果"=“後的內容在字符串中出現則匹配,但不返回”="後的內容
(?!..) 用於正則表達式之後,表示如果"!“後的內容在字符串中出現則匹配,但不返回”!"後的內容
(?<=…) 用於正則表達式之前,與(?=…)含義相同
(?<!..) 用於正則表達式之前,與(?!..)含義相同

匹配對象與組的使用

三個函數可以查看最後的結果

group([group1,...])# 返回字符串
groups([default]) # 返回元組
groupdict([default]) # 返回字典

例子:匹配所有包含字母“a”的單詞

使用group,groups,groupdict輸出他們

In [84]: import re

In [85]: s = '''Life can be dreams,
    ...: Life can be great thoughts;
    ...: Life can mean a person,
    ...: Sitting in a court.'''

In [86]: r = re.compile('\\b(?P<first>\w+)a(\w+)\\b')

In [87]: m = r.search(s)

In [88]: m.groupdict()
Out[88]: {'first': 'c'}

In [89]: m.groups()
Out[89]: ('c', 'n')

In [90]: m.group(1)
Out[90]: 'c'

In [91]:

匹配對象與索引使用

一共有三個原型

start([groupid=0])
end([groupid=0])
span(groupid=0)
  • groupid爲可選參數,即分組編號,如果不傳,返回整個字符串索引
  • start()返回字符串起始索引
  • end()返回字符結束位置索引
  • span()則以元組返回以上的兩者

例子:匹配所有包含a的單詞,用索引進行輸出

In [95]: r = re.compile('\\b(?P<first>\w+)a(\w+)\\b')

In [96]: m = r.search(s,9)

In [97]: m.start()
Out[97]: 12

In [98]: m.start(1)
Out[98]: 12

In [99]: m.start(2)
Out[99]: 16

In [100]: m.end(1)
Out[100]: 15

In [101]: m.end()
Out[101]: 18

In [102]: m.span()
Out[102]: (12, 18)

In [103]: m.span(2)
Out[103]: (16, 18)

In [104]:                                                                                                               
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章