Redis-第四章節-基礎知識
Python正則表示式
1.正則表示式字串是由普通字元和元字元表示。
①元字元 ②普通字元
基本元字元
字元 | 說明 |
---|---|
\ | 轉義符,表示轉義 |
. | 表示任意一個字元 |
+ | 表示重複一次或多次 |
* | 表示重複零次或多次 |
? | 表示重複零次或一次 |
| | 選擇符號,表示“或關係“,例如:A|B表示匹配A或B |
{ } | 定義量詞 |
[ ] | 定義字元類 |
( ) | 定義分組 |
^ | 可以表示取反,或匹配一行的開始 |
$ | 匹配一行的結束 |
當以^開始時,要求一行字串的開始位置匹配;當以$結束時,要求一行字串的結束位置匹配。所以正則表示式\w+@zhi jieketang\.com和^\w+@zhi jieketang\.com$是不同的。
import re
p1=r'\w+@zhijieketang\.com'
p2=r'^\w+@zhijieketang\.com$'
text = "Tony's email is [email protected]."
m = re.search(p1,text)
print(m)
m = re.search(p2,text)
print(m)
email = '[email protected]'
m = re.search(p2,email)
print(m)
函式
re.match 嘗試從字串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。
import re
print(re.match('www', 'www.runoob.com').span()) # 在起始位置匹配
print(re.match('com', 'www.runoob.com')) # 不在起始位置匹配
#輸出結果
(0,3)
None
re.search 掃描整個字串並返回第一個成功的匹配。
import re print(re.search('www', 'www.runoob.com').span()) # 在起始位置匹配 print(re.search('com', 'www.runoob.com').span()) # 不在起始位置匹配 #輸出結果 (0, 3) (11, 14)
re.match只匹配字串的開始,如果字串開始不符合正則表示式,則匹配失敗,函式返回None;而re.search匹配整個字串,直到找到一個匹配。
findall在字串中找到正則表示式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。
import re
pattern = re.compile(r'\d+') # 查詢數字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
print(result1)
print(result2)
#輸出結果
['123', '456']
['88', '12']
re.finditer和 findall 類似,在字串中找到正則表示式所匹配的所有子串,並把它們作為一個迭代器返回。
import re
it = re.finditer(r"\d+","12a32bc43jf3")
for match in it:
print (match.group() )
# 輸出結果
12
32
43
3
split 方法按照能夠匹配的子串將字串分割後返回列表,它的使用形式如下:
re.split(pattern, string[, maxsplit=0, flags=0])
pattern:匹配的正則表示式
string:要匹配的字串。
maxsplit:分隔次數,maxsplit=1 分隔一次,預設為 0,不限制次數。
flags:標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。
import re
p = r'\d+'
text = 'AB12CD34EF'
clist = re.split(p,text)
print(clist)
clist = re.split(p,text,maxsplit=1) #最大分隔一次
print(clist)
clist = re.split(p,text,,maxsplit=2) #最大分隔兩次
print(clist)
#輸出結果
['AB','CD','EF']
['AB','CD34EF']
['AB','CD','EF']
re.sub用於替換字串中的匹配項。
re.sub(pattern, repl, string, count=0, flags=0)
- pattern : 正則中的模式字串。
- repl : 替換的字串,也可為一個函式。
- string : 要被查詢替換的原始字串。
- count : 模式匹配後替換的最大次數,預設 0 表示替換所有的匹配。
import re
p = r'\d+'
text = 'AB12CD34EF'
repace_text = re.sub(p,'',text)
print(repace_text)
#輸出結果
ABCDEF
compile 函式用於編譯正則表示式,生成一個正則表示式( Pattern )物件,供 match() 和 search() 這兩個函式使用。編譯的正則表示式可以重複使用,減少正則表示式解析和驗證,提高效率。
re.compile(pattern[, flags])
- pattern : 一個字串形式的正則表示式
- flags : 可選,表示匹配模式,比如忽略大小寫,多行模式等,具體引數為:
- re.I 忽略大小寫
- re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴於當前環境
- re.M 多行模式
- re.S 即為 . 並且包括換行符在內的任意字元(. 不包括換行符)
- re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴於 Unicode 字元屬性資料庫
- re.X 為了增加可讀性,忽略空格和 # 後面的註釋
>>>import re
>>> pattern = re.compile(r'\d+') # 用於匹配至少一個數字
>>> m = pattern.match('one12twothree34four') # 查詢頭部,沒有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 2, 10) # 從'e'的位置開始匹配,沒有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 3, 10) # 從'1'的位置開始匹配,正好匹配
>>> print m # 返回一個 Match 物件
<_sre.SRE_Match object at 0x10a42aac0>
>>> m.group(0) # 可省略 0
'12'
>>> m.start(0) # 可省略 0
3
>>> m.end(0) # 可省略 0
5
>>> m.span(0) # 可省略 0
(3, 5)
字元類
正則表示式中可以使用字元類,一個字元類定義一組字元,其中的任一字元出現在輸出字串中即匹配成功。注意每次匹配只能匹配字元類中的一個字元。
1.定義字元類
定義一個普通的字元類需要使用'['和']'元字元類。
import re
# 在輸入字串中匹配Java或java,可以使用正則表示式[Jj]ava。
p = r'[Jj]ava
m = re.search(p,'I like Java and Python')
print(m)
m = re.search(p,'I like JAVA and Python')
print(m)
m = re.search(p,'I like java and Python')
print(m)
2.字元類取反
有時需要在正則表示式中指定不想出現的字元,可以在字元類前加"^"符號。
import re
#表示非數字
p = r'[^0123456789]''
m = re.search(p,'1000')
print(m)
m = re.search(p,'Python 3')
print(m)
#遇到第一個匹配的就返回
3.區間
區間是用連字元(-)表示的,[0123456789]採用區間表示[0-9],[^0123456789]採用區間表示[^0-9]。[A-Za-z0-9]表示任何字母和數值字元類,[0-25-7]表示0、1、2、5、6、7幾個字元組成的字元類。
import re
m = re.search(r'[A-Za-z0-9]'','A10.3')
print(m)
m = re.search(r'[0-25-7],'A34879C')
print(m)
#輸出結果
<_sre.SRE_Match object;span=(0,1),match='A'>
<_sre.SRE_Match object;span=(4,5),match='7'>
4.預定義字元類
字元 | 說明 |
---|---|
. | 匹配任意一個字元 |
\\ | 匹配反斜槓\字元 |
\n | 匹配換行 |
\r | 匹配回車 |
\f | 匹配一個換頁符 |
\t | 匹配一個水平製表符 |
\v | 匹配一個垂直製表符 |
\s | 匹配任何空白字元,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字元。等價於 [^ \f\n\r\t\v]。 |
\d | 匹配一個數字字元。等價於 [0-9]。 |
\D | 匹配一個非數字字元。等價於 [^0-9]。 |
\w | 匹配任何語音的單詞字元(如:英文字母、亞洲文字等)、數字和下劃線(_)等字元。如果正則表示式編譯標誌設定為ASCII,則只匹配'[A-Za-z0-9_]'。 |
\W | 等價於 '[^\w]'。 |
量詞
表示字元或字串重複的次數。
字元 | 說明 |
---|---|
? | 出現零次或一次 |
* | 出現零次或多次 |
+ | 出現一次或多次 |
{n} | 出現零次或n次 |
{n,m} | 至少出現n次但不超過m次 |
{n,} | 至少出現n次 |
貪婪量詞會盡可能多地匹配字元;懶惰量詞儘可能少地匹配字元。大多數計算機語言的正則表示式量詞預設是貪婪的,要想使用懶惰量詞可以在量詞後面加“?”即可。
import re
# 使用貪婪量詞
m = re.search(r'\d{5,8}','87654321') #出現數字8次
print(m) #匹配字元'87654321'
# 使用惰性量詞
m = re.search(r'\d{5,8}?','87654321') #出現數字5次
print(m) #匹配字元'87654'
#輸出結果
<_sre.SRE_Match object;span=(0,8),match='87654321'>
<_sre.SRE_Match object;span=(0,5),match='87654'>
分組
如果想讓一個字串作為整體使用量詞,可將這個字串放到一對小括號中,這就是分組。
import re
p = r'(121){2}''
m = re.search(p,'121121abcabc')
print(m)
print(m.group()) #返回匹配的字串
print(m.groups()) #返回所有組的內容
p = r'(\d{3,4})-(\d{7,8})'
m = re.search(p,'010-87654321')
print(m)
print(m.group()) #返回匹配的字串
print(m.groups())
# 輸出結果
<_sre.SRE_Match object;span=(0,6),match='121121'>
121121
('121',)
<_sre.SRE_Match object;span=(0,12),match='010-87654321'>
010-87654321
('010','87654321')
1.對正則表示式進行分組不僅可以對一個字串整體使用量詞,還可以在正則表示式中引用已經存在的分組。
2.在Python程式中訪問分組時,除了可以通過組編號進行訪問,還可以通過組名進行訪問,前提是要在正則表示式中為組命名。組命名語法是在分組的左小括號後新增?P<分組名>實現。
3.反向引用分組。除了可以在程式程式碼中訪問正則表示式匹配之後的分組內容,還可以在正則表示式內部引用之前的分組。
import re
p = r'<([\w]+)>.*</\1>'
m = re.search(p,'<a>abc</a>')
print(m)
m = re.search(p,'<a>abc</b>')
print(m)
# 輸出結果
<_sre.SRE_Match object;span=(0,10),match='<a>abc</a>'>
None
4.非捕獲分組
前面介紹的分組稱為捕獲分組,就是匹配子表示式結果被暫時儲存到記憶體中,以被表示式或其他程式引用,這稱之為“捕獲”,捕獲結果可以通過組編號或組名進行引用。但是有時並不想引用子表示式的匹配結果,不想捕獲匹配結果,只是將小括號作為一個整體進行匹配,此時可以使用非捕獲分組,非捕獲分組在組開頭使用“?:"實現。
import re
s = 'img1.jpg,img2.jpg,img3.bmp'
p = r'\w+(\.jpg)'
m = re.findall(p,s)
print(m)
p = r'\w+(?:\.jpg)'
m = re.findall(p,s)
print(m)
#輸出結果
['.jpg','.jpg']
['img1.jpg','img2.jpg']