第七章先經過字符串查找電話號碼,比較了是否使用正則表達式程序的差別,明顯正則寫法更爲簡潔、易擴展。
模式:3 個數字,一個短橫線,3個數字,一個短橫線,再是4 個數字。例如:415-555-4242git
1 import re 2 ''' 3 不用正則查找模式,匹配3個數字,1個短橫線,3個數字,1個短橫線,4個數字 4 ex. 111-222-3334 5 ''' 6 7 def isPhoneNo(text): 8 if len(text) != 12: 9 return False 10 for i in range(0,3): 11 if not text[i].isdecimal(): 12 return False 13 if text[3] != '-': 14 return False 15 for i in range(4,7): 16 if not text[i].isdecimal(): 17 return False 18 if text[7] != '-': 19 return False 20 for i in range(8,12): 21 if not text[i].isdecimal(): 22 return False 23 return True 24 25 ''' 26 用正則表達式匹配上述模式 27 ''' 28 def regPhoneNo(text): 29 phoneNoReg=re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') 30 res=phoneNoReg.search(text) 31 if res != None: 32 print('phone No find by reg: '+ res.group()) 33 34 print(isPhoneNo('123-122-9090')) 35 print(isPhoneNo('1234123321')) 36 msg = 'call me at 415-443-1111 tomorrow. 415-443-2222 is my office' 37 for i in range(len(msg)): 38 tmp = msg[i:i+12] 39 if isPhoneNo(tmp): 40 print('phone No find: ' + tmp) 41 regPhoneNo(tmp) 42 print('msg find end')
Python 的正則表達式默認是「貪心」的,這表示在有二義的狀況下,它們會盡量匹配最長的字符串。正則表達式
花括號的「非貪心」版本匹配儘量最短的字符串,即在結束的花括號後跟着一個問號dom
實例:ide
''' 例子說明Python的貪心和非貪心匹配結果 ''' def showGreedReg(): greedReg=re.compile(r'(ha){3,5}') nonGreedReg=re.compile(r'(ha){3,5}?') inp='hahahahahah' r1=greedReg.search(inp) r2=nonGreedReg.search(inp) print('greed reg res: '+r1.group()) print('nongreed reg res: '+r2.group()) showGreedReg()
第7章的項目爲電話號碼和郵箱的正則提取,剪切板部分此處省略。spa
1 import pyperclip, re 2 phoneReg=re.compile(r'''( 3 (\d{3}|\(\d{3}\))? #area code 4 (\s|-|\.)? #separator 5 (\d{3}) #first 3 digits 6 (\s|-|\.)? #separator 7 (\d{4}) #last 4 digits 8 (\s*(ext|x|ext.)\s*(\d{2,5}))? 9 )''', re.VERBOSE 10 ) 11 12 emailReg=re.compile(r'''( 13 [a-zA-Z0-9_-]+ #username 14 @ #@ 15 [a-zA-Z0-9_-]+ #domain name 16 (\.[a-zA-Z]{2,4}) 17 )''', re.VERBOSE 18 )
電話號碼從一個「可選的」區號開始,因此區號分組跟着一個問號。code
由於區號可能只是3 個數字(即\d{3}),或括號中的3 個數字(即\(\d{3}\)),因此應該用管道符號鏈接這兩部分。blog
能夠對這部分多行字符串加上正則表達式註釋# Area code,幫助你記憶(\d{3}|\(\d{3}\))?要匹配的是什麼。
電話號碼分割字符能夠是空格(\s)、短橫(-)或句點(.),因此這些部分也應該用管道鏈接。ip
這個正則表達式接下來的幾部分很簡單:3 個數字,接下來是另外一個分割符,接下來是4 個數字。ci
最後的部分是可選的分機號,包括任意數目的空格,
接着ext、x 或ext.,再接着2 到5 位數字。字符串
E-mail 地址的用戶名部分是一個或多個字符,字符能夠包括:小寫和大寫字母、數字、句點、下劃線、百分號、加號或短橫。
能夠將全部這些放入一個字符分類:[a-zA-Z0-9._%+-]。
域名和用戶名用@符號分割,域名容許的字符分類要少一些,只容許字母、數字、句點和短橫:[a-zA-Z0-9.-]。
最後是「dot-com」部分(技術上稱爲「頂級域名」),它實際上能夠是「dot-anything」。它有2 到4 個字符。
re.VERBOSE,忽略正則表達式字符串中的空白符和註釋
至此,第七章內容結束,實踐項目 強口令檢測 見下期博客