1. 程式人生 > 資料庫 >Redis-第四章節-基礎知識

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 : 可選,表示匹配模式,比如忽略大小寫,多行模式等,具體引數為:
    1. re.I 忽略大小寫
    2. re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴於當前環境
    3. re.M 多行模式
    4. re.S 即為 . 並且包括換行符在內的任意字元(. 不包括換行符)
    5. re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴於 Unicode 字元屬性資料庫
    6. 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']