# 不用正規表示式來查詢文字模式(匹配一個電話號碼,格式為:415-555-4242)
def phone_num(text): if len(text) != 12: return False for i in range(0,3): if not text[i].isdecimal(): return False if text[3] != "-": return False for i in range(4,7): if not text[i].isdecimal(): return False if text[7] != "-": return False for i in range(8,12): if not text[i].isdecimal(): return False return True if __name__ == "__main__": message = input(">>>:") for i in range(len(message)): chunk = message[i:i+12] if phone_num(chunk): print ("\033[31;1mphone num\033[0m:%s"%chunk) # >>>: Call me at 415-555-1011 tomorrow. 415-555-9999 is my office # phone num:415-555-1011 # phone num:415-555-9999
# 用正規表示式查詢文字模式
import re phone_num_re = re.compile(r"\d\d\d-\d\d\d\-\d\d\d\d") number = input(">>>:") chunk_re = phone_num_re.search(number) print ("\033[31;1mphone_num_re\033[0m:%s"%chunk_re.group()) # >>>: Call me at 415-555-1011 tomorrow # phone_num_re:415-555-1011 chunk_re_find = phone_num_re.findall(number) print ("\033[31;1mphone_num_re\033[0m:%s"%chunk_re_find) # >>>:Call me at 415-555-1011 tomorrow. 415-555-9999 is my office # phone_num_re:['415-555-1011', '415-555-9999']
# 用管道匹配多個分組
"""
字元|稱為“管道”。希望匹配許多表示式中的一個時,就可以使用它
利用findall()方法,可以找到“所有”匹配的地方
"""
import re heroRegex = re.compile(r"linux|python") mo1 = heroRegex.search("linux and python is my love") print (mo1.group()) # linux mo2 = heroRegex.findall("linux and python is my love") print (mo2) # ['linux', 'python']
# 用問號實現可選匹配
# 字元?表明它前面的分組在這個模式中是可選的
batRefex = re.compile(r"Bat(wo)?man") mo3 = batRefex.search("The Adventures of Batman") print (mo3.group())
# 用星號匹配零次或多次
batRegex1 = re.compile(r'Bat(wo)*man') mo5 = batRegex1.search('The Adventures of Batwoman') mo4 = batRegex1.search('The Adventures of Batwowowowoman') print (mo5.group()) print (mo4.group())
# 用加號匹配一次或多次
# *意味著“匹配零次或多次”,+(加號)則意味著“匹配一次或多次”。星號不要求分組出現在匹配的字串中,但加號不同,加號前面的分組必須“至少出現一次”
batRegex2 = re.compile(r'Bat(wo)+man') mo6 = batRegex2.search('The Adventures of Batwoman') print (mo6.group()) mo7 = batRegex2.search('The Adventures of Batwowowowoman') print (mo7.group()) # Batwoman # Batwowowowoman
# 用花括號匹配特定次數
"""
findall()方法
search()將返回一個Match物件,包含被查詢字串中的“第一次”匹配的文字,而findall()方法將返回一組字串,包含被查詢字串中的所有匹配。
"""
# 通配字元
# .(句點)字元稱為“萬用字元”。它匹配除了換行之外的所有字元,句點字元只匹配一個字元.
# 要匹配真正的句點,就是用倒斜槓轉義:\.
atRegex = re.compile(r'.at') print (atRegex.findall('The cat in the hat sat on the flat mat.')) # ['cat', 'hat', 'sat', 'lat', 'mat']
# 用點-星匹配所有字元
nameRegex = re.compile(r'First Name: (.*) Last Name: (.*)') mm = nameRegex.search('First Name: Al Last Name: Sweigart') print (mm.group(1)) print (mm.group(2)) # Al # Sweigart
# 用句點字元匹配換行
# 通過傳入re.DOTALL 作為re.compile()的第二個引數,可以讓句點字元匹配所有字元,包括換行字元
noNewlineRegex = re.compile('.*') # 不能匹配換行 mm2 = noNewlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group() print (mm2) # Serve the public trust. newlineRegex1 = re.compile('.*', re.DOTALL) mm3 = newlineRegex1.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group() print (mm3) # Serve the public trust. # Protect the innocent. # Uphold the law.
# 不區分大小寫的匹配
# 讓正規表示式不區分大小寫,可以向re.compile()傳入re.IGNORECASE 或re.I,作為第二個引數
robocop = re.compile(r'robocop', re.I) ro = robocop.search('RoboCop is part man, part machine, all cop.').group() print (ro) # RoboCop
# 用sub()方法替換字串
# Regex物件的sub()方法需要傳入兩個引數。第一個引數是一個字串,用於取代發現的匹配。第二個引數是一個字串,即正規表示式。sub()方法返回替換完成後的字串
namesRegex = re.compile(r'Agent \w+') resub = namesRegex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.') print (resub) # CENSORED gave the secret documents to CENSORED.
# 管理複雜的正規表示式
# 忽略正規表示式字串中的空白符和註釋,可以向re.compile()傳入變數re.VERBOSE,作為第二個引數。
# 使用了三重引號('"),建立了一個多行字串。這樣就可以將正規表示式定義放在多行中,讓它更可讀
# 示例:
phoneRegex = re.compile(r'''( (\d{3}|\(\d{3}\))? # area code (\s|-|\.)? # separator \d{3} # first 3 digits (\s|-|\.) # separator \d{4} # last 4 digits (\s*(ext|x|ext.)\s*\d{2,5})? # extension )''', re.VERBOSE)
# 組合使用re.IGNOREC ASE、re.DOTALL 和re.VERBOSE
# 可以使用管道字元(|)將變數組合起來
"""
專案:電話號碼和E-mail 地址提取程式
# 為電話號碼建立一個正規表示式
PhoneRegex = re.compile(r"(\d{3}|\(\d{3}\))?(\s|-|\.)?(\d{3})(\s|-|\.)(\d{4})(\s*(ext|x|ext.)\s*(\d{2,5}))?")
# 為E-mail 地址建立一個正規表示式
MailRegex = re.compile(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}")
參考資料:Python程式設計快速上手讓繁瑣工作自動化