1. 程式人生 > >常用模塊之re模塊以及正則表達式擴展

常用模塊之re模塊以及正則表達式擴展

之間 lap 開始 cal 第一個 默認 應該 findall 模塊名

什麽是模塊?

常見的場景:一個模塊就是一個包含了python定義和聲明的文件,文件名就是模塊名字加上.py的後綴。

但其實import加載的模塊分為四個通用類別: 

  • 使用python編寫的代碼(.py文件)
  • 已被編譯為共享庫或DLL的C或C++擴展
  • 包好一組模塊的包
  • 使用C編寫並鏈接到python解釋器的內置模塊

為何要使用模塊?

如果你退出python解釋器然後重新進入,那麽你之前定義的函數或者變量都將丟失,因此我們通常將程序寫到文件中以便永久保存下來,需要時就通過python test.py方式去執行,此時test.py被稱為腳本script。

隨著程序的發展,功能越來越多,為了方便管理,我們通常將程序分成一個個的文件,這樣做程序的結構更清晰,方便管理。這時我們不僅僅可以把這些文件當做腳本去執行,還可以把他們當做模塊來導入到其他的模塊中,實現了功能的重復利用

模塊的使用

若想要使用一個模塊,應該在程序開始的地方導入該模塊,用 import 模塊名

註意:

永遠不要起一個py文件的名字,這個名字和你已知的模塊同名

re模塊中用到的幾種方法

查找

findall:匹配所有內容,形成一個列表,每一項都是列表中的一個元素

ret = re.findall(\d+,sjkhk172按實際花費928) #正則表達式匹配 多位數字,對象是後面的字符串
print(ret) >>> [172, 928]

ret = re.findall(‘\d‘,‘sjkhk172按實際花費928‘) # 正則表達式匹配數字
print(ret) >>> [‘1‘, ‘7‘, ‘2‘, ‘9‘, ‘2‘, ‘8‘]

search:只匹配符合條件的從左到右的第一個,得到的不是直接結果,而是一個變量,通過此變量的group方法來獲得最後結果

如果沒有匹配到符合條件的,則會返回None,使用group會報錯

日常使用推薦用search,findall因一次找到所有匹配項,占內存, match相當於search的正則表達式中加了一個"^"

ret = re.search(\d+,sjkhk172按實際花費928)
print(ret)  >>><re.Match object; span=(5, 8), match=
172># 內存地址,這是一個正則匹配的結果 print(ret.group()) >>> 172# 通過ret.group()獲取真正的結果 ret = re.search(\d,owghabDJLBNdgv) print(ret) print(ret.group()) #正則沒有匹配到,所以會報錯 ret = re.search(\d+,sjkhk3256按實際花費928) if ret : # 內存地址,這是一個正則匹配的結果 print(ret.group()) >>> 3256 # 通過ret.group()獲取真正的結果

match:從頭開始匹配,相當於search中的正則表達式加上一個"^"

ret = re.match(\d+,132sjkhk按156實際花費928)
print(ret.group()) >>> 132

字符串處理的擴展

split:切割

技術分享圖片
s = alex83taibai40egon25
ret = re.split(\d+,s)
print(ret) >>> [alex, taibai, egon, ‘‘] # 以數字切割,切割對象後面默認有一個字符
View Code

sub:替換

sub(舊,新,對象,替換次數)

技術分享圖片
ret = re.sub(\d+,H,alex83taibai40egon25) # 默認全部替換
print(ret) >>> alexHtaibaiHegonH

ret = re.sub(\d+,H,alex83taibai40egon25,1)  #替換一次
print(ret) >>> alexHtaibai40egon25
View Code

subn:也是替換,不過會返回一個元組,元組中第一個原始是替換後的結果,第二個元素是替換的次數

技術分享圖片
ret = re.subn(\d+,H,alex83taibai40egon25)
print(ret) >>> (alexHtaibaiHegonH, 3)
View Code

re模塊的進階

compile:節省使用正則表達式解決問題的時間,將正則表達式編譯成字節碼,多次使用過程中不會再多次編譯,直接拿來用

ret = re.compile(\d+)   # 已經完成編譯了
print(ret)  >>> re.compile(\\d+) #編譯成原型
res = ret.findall(alex83taibai40egon25) # 拿來直接用
print(res)  >>> [83, 40, 25]
res = ret.search(sjkhk172按實際花費928) #可以多次使用,不用再次編譯
print(res.group()) >>> 172

finditer:節省使用正則表達式解決問題的空間,也就是內存

返回一個叠代器,所有的結果都在這個叠代器中,需要通過循環+group的形式取值 能夠節省內存

ret = re.finditer(\d+,alex83taibai40egon25)
print(ret) >>><callable_iterator object at 0x000001FE0DEE11D0> #調用/得到叠代器
for i in ret:
    print(i.group()) >>> 83 40 25

正則表達式的分組在re模塊中的使用

技術分享圖片
#正常使用的正則表達式
s = <a>wahaha</a>  # 標簽語言 html 網頁
ret = re.search((<\w+>)(\w+)(</\w+>),s)
print(ret.group())  >>> <a>wahaha</a> # 所有的結果
print(ret.group(1))  >>> <a># 數字參數代表的是取對應分組中的內容 第一個分組中的
print(ret.group(2)) >>> wahaha # 第二個分組中內容
print(ret.group(3))  >>> </a>
不在re模塊中的正則表達式有分組

正則表達式的分組在熱模塊中,為了findall也可以順利取到分組中的內容,有一個特殊的語法,優先顯示分組中的內容

s = <a>wahaha</a>
ret = re.findall((\w+),s)  
print(ret)  >>> [a, wahaha, a]
ret = re.findall(>(\w+)<,s)  #優先尋找匹配括號中的內容
print(ret) >>> [wahaha]

如果想取消分組優先

形式:(?:正則表達式)

ret = re.findall(\d+(\.\d+),1.234*4) 
print(ret) >>> [.234]

ret = re.findall(\d+(?:\.\d+),1.234*4) #取消了分組優先
print(ret) >>> [1.234]

分組命名

形式: (?P<這個組的名字>正則表達式)

對於正則表達式來說 有些時候我們需要進行分組,來整體約束某一組字符出現的次數 (\.[\w]+)?

對於python語言來說 分組可以幫助你更好更精準的找到你真正需要的內容 <(\w+)>(\w+)</(\w+)>

python和正則表達式之間有特殊的約定,要求使用這個名字的分組和前面同名分組中的內容匹配的必須一致

s = <a>wahaha</a>
pattern = <(?P<tab>\w+)>(\w+)</(?P=tab)>
ret = re.search(pattern,s)
print(ret.group()) >>> <a>wahaha</a>
#與 正則表達式(<\w+>)(\w+)(</\w+>)效果是一樣的
#如果正則表達式中有一模一樣的表達式 就可以命名這個表達式,後面就可以直接套用名字

正則表達式使用技巧

#若我們現在想在一個字符串中取出所有的整數,我們是不是這麽寫
ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))")
#我們打印看看
print(ret) >>> [1, 2, 60, 40, 35, 5, 4, 3]
#結果將其中小數分開也匹配上了,跟我們的需求不一樣,因為我們是要取整數的,所以,我們要這麽寫.
原因:你要匹配的內容太沒有特點了 容易和你不想匹配的內容混在一起

ret = re.findall(r"\d+\.\d+|\d+","1-2*(60+(-40.35/5)-(-4*3))")#將小數和整數都匹配出來
print(ret) >>> [1, 2, 60, 40.35, 5, 4, 3]
ret = re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
print(ret) >>> [1, 2, 60, ‘‘, 5, 4, 3]
ret.remove(‘‘)
print(ret) >>> [1, 2, 60, 5, 4, 3]

常用模塊之re模塊以及正則表達式擴展