python中對正則表達式re包的簡單引用方式
對正則表達式re包的簡單引用
正則表達式一直是被我所忽略的東西,因為在之前的學(xué)習(xí)和開發(fā)中基本很少用到它。而且,之前學(xué)習(xí)正則表達式時感覺很懵逼,所以毅然決然的放棄了(QAQ),然而出來混總歸還是要還的。最近在弄日志處理時,必須用到正則表達式,這就讓我不得不拿起正則表達式了。在此記錄一些自己學(xué)習(xí)的筆記與案例。
在python中導(dǎo)入re包
import re ?
一、re.match(pattern,string,flags=0)
嘗試從字符串 開始 位置(看清楚,開始位置?。。。┢ヅ湟粋€模式。成功則返回一個match對象,失敗則是none
參數(shù)說明:
pattern
:正則表達式string
:字符串flags
:可選標志位
注:可選標志在下面簡單說明
獲取對象的方法:
使用group(num) 來獲取對象小組內(nèi)的內(nèi)容。
舉例:
#_*_coding:utf8_*_ import re str1='010-011-110' pattern = r'\d{3}-\d{3}-\d{3}' match = re.match(pattern,str1) print match.group() print match.group(0) print match.group(1) print match.group(2) print match.group(3) #輸出為: 010-011-110 010-011-110 010 011 110
match()方法最重要的一點就是它是從字符串開始匹配的,切記這一點······我已經(jīng)在這點上犯了很多錯誤了。
在寫簡單的正則表達式的時候我們可以用()來進行分組,以便于我們在后續(xù)處理中取值。后續(xù)也會談到通過命名捕獲的方式來取值。
二、re.search(pattern,string,flags=0)
跟match函數(shù)參數(shù)一樣,它也是用來匹配字符串的。而最大的不同在于它可以從字符串的任意位置匹配,不像match一樣,僅限于從字符串開始位置。參數(shù)跟match一樣,就不做說明了,直接上例子。
#與match例子不同,001前面有很多空格 str1=' 001-010-110' #與match中的模式一樣 pattern = r'\d{3}-\d{3}-\d{3}' #若此時用match()函數(shù),結(jié)果肯定是不匹配的。 search = re.search(pattern,str1) print search.group() print search.group(0) print search.group(1) print search.group(2) print search.group(3) #結(jié)果: 001-010-110 001-010-110 001 010 110
對于match和search,還是得說一遍,注意一個必須是從字符串開始處匹配,一個是任意位置。
三、檢索和替換 re.sub()
用于替換字符串中的匹配項
re.sub(pattern,repl,string,count,flags)
參數(shù)說明:
pattern
:正則表達式repl
:替換的字符串,可為一個函數(shù)string
:要被查找的原始字符串count
:被替換的次數(shù),默認替換所有匹配項flags
:標志位
#_*_coding:utf-8_*_ import re phone = "888-7777-6666 #好牛的號碼 #刪除字符串中的注釋 num = re.sub(r'#.*','',phone) print num #刪除注釋和- realphone = re.sub(r'\D','',phone) print realphone #結(jié)果為: 888-7777-6666 88877776666
sub函數(shù)理解起來不難,但要主要的是在repl參數(shù)的使用。repl可以為一個函數(shù)。例如:
將字符串中的數(shù)字乘以二
def double(match): ? ? value = int(match.group('value')) ? ? return str(value*2) s='APPLE23EFG567' print re.sub(r'(?P<value>\d+)',double,s) ? #結(jié)果為: ?APPLE46EFG1134
因為repl為一個函數(shù),所以再替換的時候會替換為函數(shù)的返回值。
注:?P<value>為正則表達式的命名捕獲,在下面將會做簡單記錄
四、正則表達式之命名捕獲
格式為: ?P<name>
在處理字符串取值時往往會用到
例子:
num = '001-010-110' pattern = r'(\d{3})-(\d{3})-(\d{3})' match = re.match(pattern,num) print match.group() #001-010-110 print match.group(1) #001 print match.group(2) #010 print match.group(3) #110
在上述例子要分別獲取每項的值就要使用group(num),而當(dāng)正則表達式變得復(fù)雜的時候,再用num取值時,很有可能會取到錯誤的值。所以就提出使用命名捕獲,下面為簡單例子:
pattern = r'(?P<Area>\d{3})-(?P<zhong>\d{3})-(?P<wei>\d{3})' match = re.match(patter, num) ? print match.group('Area') ? ? #001 print match.group('zhong') ? ?#010 print match/group('wei') ? ? ?#110
雖然在上述例子中使用命名捕獲會將降低正則表達式的可讀性,但命名捕獲咋復(fù)雜的正則中,會準確獲取想要的值(當(dāng)然,正則肯定得寫準確啊·····)
re庫的正確使用姿勢
前提假設(shè):
- 已經(jīng)充分掌握PCRE風(fēng)格正則表達式
- 熟讀re庫文檔
Why
正則表達式的強大已不用我贅述,Python 對此的支持也是十分強大,只不過:
re.search(pattern, string, flags=0) re.match(pattern, string, flags=0) ......
你能很麻利地使用如上所示的一系列模塊級別function 嗎,如果你天天用 Python 搞正則匹配,相信你一定很熟練。但是如果你需要每次臨時翻閱文檔才能知道如何使用它,那么就要思考:是不是 API 在某種程度上設(shè)計不好了(有的語言的 pattern 極有可能不是放在首位)。
一般來說,API 的接口參數(shù)越少越好,最好的就是沒有參數(shù),調(diào)用者無腦調(diào)用,沒有任何記憶負擔(dān)。而 Python 的 re 庫,在我看來,應(yīng)該至少糅合了「命令式」與「OOP」兩種風(fēng)格,而且接口也不「最小化,正交」。
使用姿勢
正確的姿勢應(yīng)該是:只用 OOP 風(fēng)格,并且完全忘記 re 庫提供的一系列模塊級別的 function (如 re.search, re.match等)。
首先是每次都構(gòu)造出 Regex 對象,然后由 Regex 對象得出 Match 對象,然后在 Regex 對象和 Match 對象上進行一系列操作。比如:
# 1. 構(gòu)造 REGEX = re.compile($pattern, flags) flags是re模塊的常量 # 2. 獲取 MatchObject m = regex.search(string) # 3. 后續(xù) MatchObject 的使用 1. 獲取分組 group() 2. groups 3. groupdict()
應(yīng)用舉例
比如我在自己構(gòu)造的 PathUtils 中,就是如此使用的(我非常喜歡各種各樣的 Utils ):
from __future__ import (absolute_import, unicode_literals) import re class PathUtils(object): """路徑操作的工具函數(shù)""" _LINUX_ROOT = '/' _LINUX_PATH_SPLITOR = '/' @classmethod def is_two_linux_path_contains(cls, path1, path2): """兩個Linux路徑是否存在互相包含關(guān)系""" if path1 == cls._LINUX_ROOT or path2 == cls._LINUX_ROOT: return True path1_split = path1.split(cls._LINUX_PATH_SPLITOR) path2_split = path2.split(cls._LINUX_PATH_SPLITOR) for item1, item2 in zip(path1_split, path2_split): if item1 != item2: return False return True @classmethod def is_valid_linux_path(cls, path): if not path: return False LINUX_PATH_REGEX = r'^(/[^/ ]*)+/?$' return cls.is_valid_pattern(path, LINUX_PATH_REGEX) @classmethod def is_valid_windows_path(cls, path): if not path: return False WINDOWS_PATH_REGEX = r'^[a-zA-Z]:\\(((?![<>:"/\\|?*]).)+((?<![ .])\\)?)*$' return cls.is_valid_pattern(path, WINDOWS_PATH_REGEX) @classmethod def is_valid_path(cls, p): if not p: return False return cls.is_valid_linux_path(p) or cls.is_valid_windows_path(p) @classmethod def is_valid_pattern(cls, value, pattern): if not value: return False REGEX = re.compile(pattern, re.UNICODE) m = REGEX.match(value) return True if m else False
主要的功能函數(shù)就是:
@classmethod def is_valid_pattern(cls, value, pattern): ? ? if not value: ? ? ? ? return False? ? ? REGEX = re.compile(pattern, re.UNICODE)? ? ? m = REGEX.match(value)? ? ? return True if m else False
這樣一系列流程下來,我的感受就是,re 庫的接口沒有需要記憶,也沒有需要臨時翻閱文檔的地方,并且我只用這一種風(fēng)格(自己熟悉的,效率總是最高的),比如 re.compile肯定只需要傳一個參數(shù)(flags不是必要的),REGEX_OBJ.match/search肯定只需要傳need_search_string即可。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python3和pyqt5實現(xiàn)控件數(shù)據(jù)動態(tài)顯示方式
今天小編就為大家分享一篇Python3和pyqt5實現(xiàn)控件數(shù)據(jù)動態(tài)顯示方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12django框架自定義模板標簽(template tag)操作示例
這篇文章主要介紹了django框架自定義模板標簽(template tag)操作,結(jié)合實例形式分析了Django框架自定義模板標簽原理、操作步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2019-06-06Python機器學(xué)習(xí)之實現(xiàn)模糊照片人臉恢復(fù)清晰
GFPGAN是騰訊開源的人臉修復(fù)算法,它利用預(yù)先訓(xùn)練好的面部?GAN(如?StyleGAN2)中封裝的豐富和多樣的先驗因素進行盲臉?(blind?face)修復(fù)。這篇文章主要為大家介紹通過GFPGAN實現(xiàn)模糊照片人臉恢復(fù)清晰,需要的朋友可以參考一下2021-12-12python中queue.Queue之task_done的用法
這篇文章主要介紹了python中queue.Queue之task_done的用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02Python爬蟲自動化獲取華圖和粉筆網(wǎng)站的錯題(推薦)
這篇文章主要介紹了Python爬蟲自動化獲取華圖和粉筆網(wǎng)站的錯題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01Python爬蟲實戰(zhàn)演練之采集糗事百科段子數(shù)據(jù)
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Python采集糗事百科段子的數(shù)據(jù),大家可以在過程中查缺補漏,提升水平2021-10-10Python Pickling 和 Unpickling 的區(qū)別
Python中的Pickling和Unpickling是與數(shù)據(jù)序列化和反序列化相關(guān)的重要概念,本文主要介紹了Python Pickling和Unpickling的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2023-11-11在ubuntu16.04中將python3設(shè)置為默認的命令寫法
這篇文章主要介紹了在ubuntu16.04中將python3設(shè)置為默認python的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧2018-10-10