學習Regex筆記(三),學習Regex筆記
Python的 re 模組:核心函數和方法1. 使用 compile()函數編譯Regex
匯入 re 模組後,在compile() 中編譯Regex,例如:pattern = re.compile('Regex',re.S),然後就可以使用pattern來進行匹配了。
在compile 中還可以帶模組屬性,即re.S,re.I,re.L,re.M,re.X等。
2.匹配對象以及 group()和 groups()方法
匹配對象有兩個主要的方法:group()和 groups()。 調用 match()或者 search()返回的對象就是匹配對象,group()要麼返回整個匹配對象,要麼根據要求返回特定子組。
groups()則僅返回一個包含唯一或者全部子組的元組。如果沒有子組的要求,那麼當group()仍然返回整個匹配時,groups() 返回一個空元組。
3. 使用 match()方法匹配字串
match() 函數試圖從字串的起始部分對模式進行匹配。如果匹配成功,就返回一個匹配對象;如果 匹配失敗,就返回 None,匹配對象的 group()方法能夠用於顯示那個成功的匹配。
1 html = '<html><head>title</head><body>2333</body></html>' 2 pattern = re.compile('<.*?head>(.*?)<.*?body>(.*?)<.*?>') 3 4 m = re.match(pattern, html) 5 6 print(m.group()) 7 print(m.group(1)) 8 print((m.group(2))) 9 print(m.groups())10 # 輸出:11 # <html><head>title</head><body>2333</body>12 # title13 # 2333
14 # ('title', '2333')
>>> re.match('foo', 'food on the table').group() 'foo' 4. 使用 search()在一個字串中尋找模式,(搜尋)
search()的工作方式與 match()完全一致,不同之處在於 search()會用它的字串參數,在任意位置對給定Regex模式搜尋第一次出現的匹配情況。
如果搜尋到成功的匹配,就會返回一個匹配對象;否則,返回 None。
search() 和 match() 不同之處在於,search() 會搜尋字串中間部分。
>>> m = re.match('foo', 'seafood') # 匹配失敗 >>> m = re.search('foo', 'seafood') # 使用 search() 代替 >>> if m is not None: m.group() ... 'foo' # 搜尋成功,但是匹配失敗,在seafood中搜尋foo 5.重複、特殊字元以及分組
用一個匹配電子郵件地址的Regex做例子。(\w+@\w+\.com),這個Regex只能匹配簡單的地址。
為了在網域名稱前添加主機名稱支援,例如 www.xxx.com,需要使用?,\w+@(\w+\.)?\w+\.com,讓(\w+\.)可選。
>>> pattern = '\w+@(\w+\.)?\w+\.com' >>> re.match(pattern, 'nobody@xxx.com').group() 'nobody@xxx.com' >>> re.match(pattern, 'nobody@www.xxx.com').group()
'nobody@www.xxx.com'
進一步擴充該樣本,允許任意數量的中間子網域名稱存在。把?改為 * 號。\w+@(\w+\.)*\w+\.com
>>> patt = '\w+@(\w+\.)*\w+\.com' >>> re.match(patt, 'nobody@www.xxx.yyy.zzz.com').group()
'nobody@www.xxx.yyy.zzz.com'
使用圓括弧來匹配和儲存子組,以便於後續處理。
>>> m = re.match('(\w\w\w)-(\d\d\d)', 'abc-123') >>> m.group() # 完整匹配 'abc-123' >>> m.group(1) # 子組 1 'abc' >>> m.group(2) # 子組 2 '123' >>> m.groups() # 全部子組 ('abc', '123')
group()通常用於以普通方式顯示所有的匹配部分,但也能用於獲 取各個匹配的子組。可以使用 groups()方法來擷取一個包含所有匹配子字串的元組。
6.使用 sub()和 subn()搜尋與替換
有兩個函數/方法用於實現搜尋和替換功能:sub()和 subn()。兩者幾乎一樣,都是將某字串中所有匹配Regex的部分進行某種形式的替換。
用來替換的部分通常是一個字串, 但它也可能是一個函數,該函數返回一個用來替換的字串。
subn()和 sub()的不同點是subn() 還返回一個表示替換的總數,替換後的字串和表示替換總數的數字一起作為一個擁有兩個元素的元組返回。
>>> re.sub('X', 'Mr. Smith', 'attn: X\n\nDear X,\n') 'attn: Mr. Smith\012\012Dear Mr. Smith,\012' >>> >>> re.subn('X', 'Mr. Smith', 'attn: X\n\nDear X,\n') ('attn: Mr. Smith\012\012Dear Mr. Smith,\012', 2) >>> >>> print(re.sub('X', 'Mr. Smith', 'attn: X\n\nDear X,\n'))attn: Mr. Smith Dear Mr. Smith, >>> re.sub('[ae]', 'X', 'abcdef') 'XbcdXf' >>> re.subn('[ae]', 'X', 'abcdef') ('XbcdXf', 2) 7.擴充符號
通過使用 (?iLmsux) 系列選項,使用者可以直接在Regex裡面指定一個或者多個標 記,而不是通過 compile()或者其他 re 模組函數。
下面為一些使用 re.I/IGNORECASE 的樣本, 最後一個樣本在 re.M/MULTILINE 實現多行混合:
>>> re.findall(r'(?i)yes', 'yes? Yes. YES!!') # (?i) 不區分大小寫 ['yes', 'Yes', 'YES'] >>> re.findall(r'(?i)th\w+', 'The quickest way is through this tunnel.') ['The', 'through', 'this'] >>> re.findall(r'(?im)(^th[\w ]+)', """ ... This line is the first, ... another line, ... that line, it's the best ... """) ['This line is the first', 'that line']