1. 程式人生 > >Python正則表示式基本教程

Python正則表示式基本教程

正則表示式是一個特殊的字元序列,它能幫助你方便的檢查一個字串是否與某種模式匹配。

Python 自1.5版本起增加了re 模組,re模組使Python語言擁有全部的正則表示式功能。

1. 常見正則表示式: 

1.1 字元類

[aeiou] 匹配中括號內的任意一個字母
[0-9] 匹配任何數字。等價於[0123456789]或\d
[a-z] 匹配任何小寫字母
[A-Z] 匹配任何大寫字母
[a-zA-Z0-9] 匹配任何字母及數字
[^aeiou] 除了aeiou字母以外的所有字元
[^0-9] 匹配除了數字外的字元。等價於\D

例:

[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"

1.2 特殊字元類

. 匹配除 "\n" 之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用象 '[.\n]' 的模式。
\d 匹配一個數字字元。等價於 [0-9]。
\D 匹配一個非數字字元。等價於 [^0-9]。
\s 匹配任何空白字元,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。
\S 匹配任何非空白字元。等價於 [^ \f\n\r\t\v]。空白字元即沒有東西顯示的字元。
\w 匹配包括下劃線的任何字母、數字或下劃線。等價於'[A-Za-z0-9_]'。
\W 匹配任何非字母、陣列或下劃線。等價於 '[^A-Za-z0-9_]'。
\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\A 匹配字串開始。
\Z 匹配字串結束,如果是存在換行,只匹配到換行前的結束字串。
\z 匹配字串結束。
\G 匹配最後匹配完成的位置。
\n, \t等 匹配一個換行符、一個製表符等。
\1, \2等 匹配第n個分組的內容。

1.3 其他特殊字元

備註:re表示任意一個正則表示式。

re* 匹配0個或無限多個*前的表示式。*和+的區別在於*為至少0個,+為至少1個。
re? 匹配0個或1個由前面的正則表示式定義的片段。最多匹配1個,不能大於1個。相當於re{0,1}。
re+ 匹配1個或無限多個+前的表示式。
re{n} 精確匹配n個前面表示式。
re{n, m} 匹配 n 到 m 次由前面的正則表示式定義的片段,貪婪方式
^ 匹配字串的開頭。不在中括號中的時候的意思。在中括號中^表示不在[]中的字元。
[^...] 不在[]中的字元:[^abc] 匹配除了a,b,c之外的字元。
$ 匹配字串的末尾。

1.4 例子

例1:      re*, re+, re? 三者的區別

>>>import re

>>>match = re.match(r'\d?', '123456dogcatdog', re.I)

>>>match.group(0)

Out[31]: '1'

>>>match = re.match(r'\d+', '123456dogcatdog', re.I)

match.group(0)

Out[33]: '123456'

>>> match = re.match(r'\d*', '123456dogcatdog', re.I)

match.group(0)

Out[29]: '123456'

例2:      re*, re+, re? 三者的區別

>>>import re

>>>match = re.match(r'\d*\w', 'dogcatdog', re.I) # 匹配成功,\d*匹配數字有0個也算匹配成功

>>>match.group(0)

Out[39]: 'd'

>>>match = re.match(r'\d?\w', 'dogcatdog', re.I)  # 匹配成功,\d?匹配0-1個數字

>>>match.group(0)

Out[47]: 'd'

>>>match = re.match(r'\d+\w', 'dogcatdog', re.I)  # 未匹配成功,因為\d+要求至少有一個數字。

>>>match.group(0)

AttributeError: 'NoneType' object has no attribute 'group'

例3:  re{n} 和 re{n, m} 的用法

>>>import re

>>>match = re.match(r'\w{3}', 'dogcatdog', re.I)      # r'\w{3}' 匹配長度為3的由字母/數字/下劃線組成的字串

>>>match.group(0)

Out[50]: 'dog'

>>>match = re.match(r'\w{3,6}', 'dogcatdog', re.I)     # r'\w{3,6}' 匹配長度為3-6的字串,貪心,即匹配的越長越好

>>>match.group(0)

Out[52]: 'dogcat'

2. 正則表示式處理函式

Python中常用的正則表示式處理函式有:re.match(), re.search(), re.findall(), re.sub(),使用前需要import re。

2.1 re.match(pattern, string, flags=0)

match嘗試從字串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。

匹配成功:返回一個匹配的物件。

匹配失敗:返回None。

match的引數:

pattern     正則表示式

string        要匹配的字串

flags         標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

                  re.I       使匹配對大小寫不敏感。                   re.L      做本地化識別(locale-aware)匹配。                   re.M     多行匹配,影響 ^ 和 $。                   re.S     使特殊字元" . "可以匹配包括換行在內的所有字元。                   re.U     根據Unicode字符集解析字元。這個標誌影響 \w, \W, \b, \B。                   re.X     該標誌通過給予你更靈活的格式以便你將正則表示式寫得更易於理解。

執行m = re.match()匹配成功後,檢視匹配結果的方法:

可以使用group(num)或groups()匹配物件函式,來獲取匹配到的結果。

m.group(0)                   # 檢視匹配的整個表示式的字串

m.group(num=n)         # n>0的整數,返回第n個匹配到的字串。

m.groups                     # 返回一個包含所有小組字串的元組,從 1 到 所含的小組號。

例子: 測試group

>>>import re

>>> re.match(r'dog', 'dog cat dog')

Out[21]: <_sre.SRE_Match object at 0xb743e720<

>>> match = re.match(r'dog', 'dog cat dog')

>>> match.group(0)

Out[22]: 'dog'

>>> re.match(r'cat', 'dog cat dog')     # 未匹配到,因為字串不是以cat開頭

Out[23]:                                                 # 返回值為None,打印出來看什麼也沒有

例子:   # 使用flags標誌位。

>>>import re

>>>match = re.match(r'Dog', 'dog cat dog', re.I)      # 匹配時忽略大小寫

>>>match.group(0)

Out[27]: 'dog'

2.2 re.search(pattern, string, flags=0):

search掃描整個字串並返回第一個成功的匹配。

注意:只返回第一個匹配!!!

m = re.search()

search的引數:

pattern     正則表示式 string       要匹配的字串 flags        標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

例子:

>>>import re

>>> match = re.search(r'cat', 'dog cat dog')

>>> match.group(0)

Out[17]: 'cat'

例子:

>>>import re

>>>str = r'air_00a91d42b08b08d9_2017-04-23'

>>>match = re.search(r'(air_.*)_(.*)', str)            # 括號括起來的內容表示處於同一組,可以用group(num)分組檢視匹配結果

>>>match.group(0)

Out[18]: 'air_00a91d42b08b08d9_2017-04-23'

>>>match.group(1)

Out[19]: 'air_00a91d42b08b08d9'

>>>match.group(2)

Out[20]: '2017-04-23'

>>>match.group(3)               # 報錯,因為沒有3

Out[21]: IndexError: no such group

2.3 re.findall(pattern, string, flags=0):

返回所有匹配成功的字串組成的列表,返回值型別為list

與search的區別:search只返回匹配成功的第一個字串,而findall會將所有匹配成功的字串都返回。

findall的引數:

pattern     正則表示式 string        要匹配的字串 flags         標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

例子:

>>>import re

>>>re.findall(r'dog', 'dog cat dog')

Out[15]: ['dog', 'dog']

2.4 re.sub(pattern, repl, string, count=0, flags=0):  

# 匹配並替換

匹配所有字串?還是匹配一個?,然後用repl替換匹配成功的子字串。

sub的引數:

pattern     正則表示式

repl          用repl來替換匹配到的字串,repl也可為一個函式。

string       要匹配的字串

count       為0表示所有匹配到的子字串都替換為repl,為大於0的整數表示最多替換count個

flags        標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

例子:

>>>import re

>>>phone = "2004-959-559# 這是一個國外電話號碼"

>>>num = re.sub(r'#.*$', "", phone)   # 刪除字串中的 Python 註釋

>>>print "電話號碼是: ", num

Out:  電話號碼是:  2004-959-559

>>>num = re.sub(r'\D', "", phone)      # 將所有非數字的字元替換為空

>>>print "電話號碼是 : ", num

Out:  電話號碼是 :  2004959559