大家好,這里是程序員晚楓。
今天用一道華為筆試題,帶大家深入掌握一項Python技巧:正則表達式。
本文主要分為4個部分:題目解析、常用方法、專業方法、注意事項
先來看一下題目。
看完題目,有以下2個解題思路:
def?cut_8ch(str): ????if?len(str)?<?8: ????????str?=?str.ljust(8,?'0') ????elif?len(str)?>?8: ????????if?(len(str)?%?8)?!=?0: ????????????width?=?len(str)?+?(8?-?len(str)?%?8) ????????????str?=?str.ljust(width,?'0') ????str2List?=?[] ????i?=?0 ????while?i?<?len(str): ????????if?(i?+?8)?<?len(str): ????????????str2List.append(str[i:i+8]) ????????else: ????????????str2List.append(str[i:len(str)]) ????????????break ????????i?=?i?+?8 ????return?str2List output?=?[] tmp?=?input('請輸入字符串-->>').strip() output.append(cut_8ch(tmp)) for?x?in?output: ????for?y?in?x: ????????print(y)
import?re str?=?input('請輸入字符串-->>') if?len(s)?%?8?!=?0: ????s?=?s.ljust(len(s)?+?(8?-?len(s)?%?8),?str(0)) res?=?re.findall('.{8}',?s) [print(r)?for?r?in?res]
很明顯,思路2實現起來,邏輯更清晰,代碼更簡潔。原因在哪里呢?
今天我們重點講一下re模塊的使用。 關于str的所有自帶方法,如果大家想看的話,可以在評論區告訴我,我可以另寫一個篇新的文章來介紹。
按照慣例,我們對Python知識的解析,直接拿源碼來研究。先看一下python源碼里,re模塊提供的12個方法👇
找出所有符合條件的內容。
舉例:
我們現在有一句話,里面有一些數字,我們想把這些數字都提取出來:程序員晚楓,今年18
歲,家里存款100
多,車有0
輛,多謝各位的10086
+個點贊
import?re str?=?'程序員晚楓,今年18歲,家里存款100多,車有0輛,多謝各位的10086+個點贊' res?=?re.findall('[0-9]+',string=str) print(res) #?輸出:['18',?'100',?'0',?'10086']
對字符串進行分割。
舉例:
假如我們現在有一組字符串:程序員晚楓5
程序員晚楓4
程序員晚楓7
程序員晚楓,其中混進了一些無規律的數字:5、4、7,這次我們想根據這些數字,把這個字符串分割。
import?re str?=?'程序員晚楓5程序員晚楓4程序員晚楓7程序員晚楓' res?=?re.split(pattern='[0-9]',string=str) print(res) #?輸出:['程序員晚楓',?'程序員晚楓',?'程序員晚楓',?'程序員晚楓,']
可以替換字符串中的內容。
舉例:
假如我們現在有一組字符串:程序員晚楓5
程序員晚楓4
程序員晚楓7
程序員晚楓,其中混進了一些無規律的數字:5、4、7,我們想根據這些數字,替換成逗號:,
。
import?re str?=?'程序員晚楓5程序員晚楓4程序員晚楓7程序員晚楓,' res?=?re.sub(pattern='[0-9]',?repl=',',?string=str,?count=0) print(res) #?輸出:程序員晚楓,程序員晚楓,程序員晚楓,程序員晚楓, #?----- #?參數1:pattern:表示正則中的模式字符串。 #?參數2:repl:就是replacement,表示被替換的字符串,可以是字符串也可以是函數。 #?參數3:string:表示要被處理和替換的原始字符串 #?參數4:count:可選參數,表示是要替換的最大次數,而且必須是非負整數,該參數默認為0,即所有的匹配都會被替換;
re.match()必須從字符串開頭匹配!
舉例:
match方法,可以幫我們匹配出這段文字中的英文字母,"CoderWanFeng,加好友,聯系程序員晚楓"
import?re text?=?"CoderWanFeng,加好友,聯系程序員晚楓" res?=?re.match("[a-zA-Z]+",?text) print(res)??#?查看是否匹配到結果 print(res.group())??#?取出匹配的內容
fullmatch見名知義:只有在給定的字符串全部匹配時,才返回正確。
舉例:
匹配用戶輸入的電話號碼是否都是數字+符合11位。
import?re input?=?"19512345678" pattern?=?"[0-9]+" print(re.fullmatch(pattern,?input)) print(re.fullmatch(pattern,input).group())
查找字符串中是否有符合條件的內容。
import?re str?=?"程序員晚楓" #?search?字符串第一次出現的位置 print(re.search("晚",?str)) #?輸出:<re.Match?object;?span=(3,?4),?match='晚'>
subn和sub的方法類似,區別在于:subn()方法返回一個元組,其中包含所有替換的總數以及新字符串。 看到subn方法我困惑了一下,它和sub的區別時什么?
看過源碼👇才知道,區別就是那個n。
import?re str?=?'程序員晚楓,程序員晚楓,程序員晚楓,程序員晚楓,' res?=?re.subn(pattern='程序員晚楓',?repl='點贊+關注',?string=str,?count=2) print(res) #?參數1:pattern:表示正則中的模式字符串。 #?參數2:repl:就是replacement,表示被替換的字符串,可以是字符串也可以是函數。 #?參數3:string:表示要被處理和替換的原始字符串 #?參數4:count:可選參數,表示是要替換的最大次數,而且必須是非負整數,該參數默認為0,即所有的匹配都會被替換; #?----- #?('點贊+關注,點贊+關注,程序員晚楓,程序員晚楓,',?2)
這個方法返回的是一個迭代器。
import?re str?=?'程序員晚楓,今年18歲,家里存款100多,車有0輛,多謝各位的10086+個點贊' res?=?re.finditer('[0-9]+',string=str) print(res) #?輸出:<callable_iterator?object?at?0x000001C3E94D3F40>
re.compile()是用來優化正則的,它將正則表達式轉化為對象,re.search(pattern, string)的調用方式就轉換為 pattern.search(string)的調用方式,多次調用一個正則表達式就重復利用這個正則對象,可以實現更有效率的匹配。
如下列代碼所示,re.compile生成pattern后,依然需要調用re的方法。
import?re str?=?'程序員晚楓,今年18歲,家里存款100多,車有0輛,多謝各位的10086+個點贊' reg?=?re.compile('[0-9]+') res?=?reg.findall(string=str) print(res) #?輸出:['18',?'100',?'0',?'10086']
如源碼所說,這個方法主要是用來清楚緩存。
Python標準庫中唯一調用re.purge()的位置是在測試中(特別是test_re模塊的re單元測試和回歸測試套件中的參考泄漏測試)。
這個方法我沒找到怎么使用,歡迎大家在評論區補充。
可以將字符串中所有可能被解釋為正則運算符的字符進行轉譯。
re.escape('www.python-office.com') #?輸出:'www\\.python-office\\.com'
|