Python中正規表示式相關的都在re模組中。簡單整理一下常見的語法和方法
-
關於轉義字元
如果執行下面了下面這句程式碼:
print('a\nb')
那麼會得到這樣的結果:
並沒有列印出\n只有a和b,而且它們還換行了。如果想要列印
\n
這個字串有兩種辦法:print('a\\nb') print(r'a\nb') 複製程式碼
第一種就是再加一個轉義符號(\)將原本的轉義符轉義成原本的意思。第二種是使用
r'字串'
這種格式。推薦用第二種。 -
re.match 和 re.search
re.match 和 re.search很像,它們都用於判斷匹配是否成功,如果成功就返回一個物件,不成功就返回None
import re res_match = re.match(r'ab', 'ababababab') res_search = re.search(r'ab', 'ababababab') print(res_match) # <re.Match object; span=(0, 2), match='ab'> print(res_search) # <re.Match object; span=(0, 2), match='ab'> 複製程式碼
它們兩的區別在於,如果字串的開頭就匹配失敗,match方法會直接返回None,search則會繼續匹配下去。例子:
import re res_match = re.match(r'ab', 'ccccababababab') res_search = re.search(r'ab', 'ccccbababababab') print(res_match) # None print(res_search) # <re.Match object; span=(5, 7), match='ab'> 複製程式碼
match和search方法返回的物件中span表示匹配成功的字元的位置,match則是匹配結果,它們返回的物件都有group和groups方法。
直接看例子:
import re res_match = re.match(r'(ab)-(cd)-(ef)', 'ab-cd-ef') print('group不帶引數:', res_match.group()) print('group帶引數:', res_match.group(1)) print('group帶引數:', res_match.group(2)) print('group帶引數:', res_match.group(3)) print('group帶多個引數:', res_match.group(1, 2, 3)) print('groups:', res_match.groups()) 複製程式碼
結果:
group和groups方法會返回匹配到的字元,如果在正規表示式中用了
()
那麼表示匹配括號內的所有內容,一個()
就是一個組, group方法接受的引數就是組的序號。組從1開始。 -
re.compile
compile方法用於建立一個正規表示式( Pattern )物件
prog = re.compile(pattern) result = prog.match(string) 複製程式碼
等價於
result = re.match(pattern, string) 複製程式碼
例子:
import re reg = re.compile(r'\d') res_match = reg.match('12313131') res_search = reg.search('abcdefg12313131') print(res_match.group()) # 1 print(res_search.group()) # 1 複製程式碼
可以看到上面例子中數字有很多個,但是隻匹配到一個就不匹配了。如果想要匹配所有符合規則的字串可以用findAll方法,例子:
import re reg = re.compile(r'\d') res_match = reg.match('12313131') res_search = reg.search('abcdefg12313131') res_findAll = reg.findall('a1h2h1312h31hjg31j3') print(res_match.group()) # 1 print(res_search.group()) # 1 print(res_findAll) # ['1', '2', '1', '3', '1', '2', '3', '1', '3', '1', '3'] 複製程式碼
-
re.sub
re.sub用於替換字串中的匹配項。它的語法是:
re.sub(pattern, repl, string, count=0, flags=0)
- pattern : 正則中的模式字串。
- repl : 替換的字串,也可為一個函式。
- string : 要被查詢替換的原始字串。
- count : 模式匹配後替換的最大次數,預設 0 表示替換所有的匹配。
例子:
import re test_str = '2012-12-21' def square(num): return str(int(num.group())**2) res = re.sub(r'\D', '/', test_str) res_func = re.sub(r'\d', square, test_str) print(res) # 2012/12/21 print(res_func) # 4014-14-41 複製程式碼
-
貪婪模式
在說貪婪模式之前,先介紹幾個特殊字元:
*, +, ?
- *: 匹配0到任意次
- +: 匹配1到任意次
- ?: 匹配0到1次
例子:
import re reg = re.compile(r'ab*') reg_1 = re.compile(r'ab+') reg_2 = re.compile(r'ab?') test_str = 'abbbbbbbbbbbbbb' res_xinghao = reg.match(test_str) res_jiahao = reg_1.match(test_str) res_wenhao = reg_2.match(test_str) print('*:', res_xinghao.group()) # *: abbbbbbbbbbbbbb print('+:', res_jiahao.group()) # +: abbbbbbbbbbbbbb print('?:', res_wenhao.group()) # ?: ab 複製程式碼
*, +, ?
它們都是貪婪模式,也是就在匹配成功的情況下,儘可能的多匹配符合規則的字元。如果想要非貪婪模式那麼只需要在它們後面各自加上
?
即可:*?, +?, ??
import re reg = re.compile(r'ab*?') reg_1 = re.compile(r'ab+?') reg_2 = re.compile(r'ab??') test_str = 'abbbbbbbbbbbbbb' res_xinghao = reg.match(test_str) res_jiahao = reg_1.match(test_str) res_wenhao = reg_2.match(test_str) print('*?:', res_xinghao.group()) # *?: a print('+?:', res_jiahao.group()) # +?: ab print('??:', res_wenhao.group()) # ??: a 複製程式碼
正規表示式還有很多的特殊字元,也叫元字元。官方文件解釋的更清楚,這裡就不寫了。它們的組合很多,這也是我覺得正則難的原因。