目錄
一、正則表達式的基本概念
1、基本概念
2、正則表達式的特殊字符
二、范圍符號和量詞
1、范圍符號
2、匹配漢字
3、量詞
三、正則表達式函數
1、使用正則表達式:
2、re.match()函數
3、re.search()函數
4、findall()函數
5、re.finditer()函數
6、迭代器
7、re.sub()函數
四、邊界符號
五、分組
在Python的正則表達式中,我們可以用它來判斷某個字符串是否符合某種模式,比如判斷某個字符串是不是郵箱地址,是不是電話號碼等,我們可以利用正則表達式在文本中尋找并抽取符合某種模式或格式
一、正則表達式的基本概念
1、基本概念
正則表達式是一個某些字符擁有一些特殊含義的字符串
下面我們介紹幾個有特殊含義的功能字符:
字符組合 | 匹配模式 |
. | 除了\n外的任意一個字符,包括漢字(多行匹配可能也包含\n) |
* | 量詞,表示其左邊的字符可出現0次或任意多次(包括一次) |
? | 量詞,表示其左邊的字符必須出現一次或0次 |
+ | 量詞,表示其左邊的字符必須出現一次或更多次 |
{ m } | 量詞,m是整數,表示其左邊的字符必須且只能出現m次 |
{ m,n } | 量詞,m和n都是整數,表示左邊的字符至少出現m次,至多n次(n也可以不寫,表示沒有上限 |
\d | 一個數字字符,等價于[0 , 9] |
\D | 一個非數字字符,等價于[^\d] , [^0 , 9] |
\s | 一個空白字符,如空格,\t , \r , \n |
\S | 一個非空白字符 |
\w | 一個單詞字符,包括漢字或大小寫的英文字母,數字,下劃線,或其他語言的 |
\W | 一個非單詞符 |
| | A | B,表示能匹配A或能匹配B均算能匹配 |
(注:上述這些組合是兩個獨立的字符,單純的在字符串里面輸出的話無效果,需結合相關的正則表達式函數!)
2、正則表達式的特殊字符
我們在正則表達式中常見的特殊字符有以下幾個
.? +? ?? *? $? [? ]? (? )? ^? {? }? \??
如果要在正則表達式中使用上述這些字符本身,我們在前面加上\符號
(注:和剛剛上面一樣,這些特殊字符加\符號只是兩個獨立的字符,本身無特殊含義,如果只是在字符串中輸出,無效果,需結合正則表達式使用)
二、范圍符號和量詞
1、范圍符號
在正則表達式中我們的范圍符號用[]來表達,這個符號的意思是此處必須出現一個中括號內的所指定的范圍的字符
相關用法:
例子用法 | 含義 |
[abc] | 此處需匹配a,b,c中的一個字符 |
[a-zA-Z] | 匹配任意英文字母 |
[\da-z\$] | 匹配一個數字或任意一個小寫字母,或字符$ |
[^abc] | 匹配一個字符,但不能是abc中的一個 |
[^a-k5-9] | 匹配一個字符,但不能是a到k中的一個,或者不能是5 到9中的一個 |
2、匹配漢字
漢字的Unicode編碼范圍是 4e00 - 9fa5 (16進制)因此[4e00 - 9fa5]就是表示一個漢字
3、量詞
量詞的使用十分靈活,我們可以把量詞和上面提到的特殊字符結合起來,達到更加細致的匹配條件:
比如,我們可以把 . 和 + 結合起來,“ . ”代表任意字符(除了\n),而+表示出現或多次(出現的字符不見得需要一樣),結合起來就代表著匹配任意長度不為0且不包含\n的字符串
我們還可以在前面加上負號,來表示數字的范圍:
正整數:[1-9]\d*(數字的最前面不能是0,所以先規定1-9,然后的\d是一個0-9的數字,再加一個*就是說這個\d可以出現0次或多次)
負整數:-[1-9]\d*(前面加一個負號即可)
整數:-?[1-9]\d* | 0(?表示可能出現一次或0次,涵蓋了正負整數,再用|符號加一個0,就是全部整數)
三、正則表達式函數
1、使用正則表達式:
我們如果想要使用正則表達式,需要先調用re包
import re
2、re.match()函數
re.match()函數的格式:
re.match(pattern , string , flags = 0)
①從字符串string的起始位置匹配對應的正則表達式pattern
②flags是標志位,用于控制模式串的匹配方式,比如,是否區分大小寫,多行匹配等,例子:re.M | re.I就是忽略大小寫,且多行匹配
③成功就返回一個匹配對象,否則返回None
下面我們來看一個例子:
import redef match(pattern , string) :x = re.match(pattern , string)if x != None :print(x.group()) #group()是返回匹配到的字符串else :print(None)match("scy" , "scymimimi") #符合要求match("scy" , "mimiscymimi") #雖然包含scy,但是不是在開頭match(".{3}scy" , "miscyabdc") #要求scy的左邊必須包含三個字符,但是string中只有兩個
輸出:
3、re.search()函數
re.search()函數的格式:
re.search(pattern , string , flags = 0)
①查找字符串中,可以匹配成功的子串
②成功就返回一個匹配對象,否則返回None
我們把上面的代碼稍加修改:
import redef matchtwo(pattern , string) :x = re.search(pattern , string)if x != None :print(x.group()) #group()是返回匹配到的字符串else :print(None)matchtwo("scy" , "scymimimi") #符合要求matchtwo("scy" , "mimiscymimi") #只要能在后面的string中找到符合規則的即可matchtwo(".{3}scy" , "miscyabdc") #要求scy的左邊必須包含三個字符,但是string中只有兩個,雖然能找到scy這個子串,但是不符合其他的條件
結果:
因為這是在整個字符串中找到符合要求的子串,如果我們的string十分的長,我們可以添加一個函數來使得查找更方便:x.span()
潤色后的代碼(只包含函數部分):
def matchtwo(pattern , string) :x = re.search(pattern , string)if x != None :print(x.group() , x.span()) #group()是返回匹配到的字符串 x.span()是輸出其子串的起止位置else :print(None)
結果:
4、findall()函數
在前面兩個函數中,無論是哪一個函數,都是只找了第一個符合目標的子串,就返回了結果,如果我們想要找到全部符合要求的子串,就可以使用findall()函數:
re.findall()函數的格式:
re.findall(pattern , string , flags = 0)
對其目標字符串string中的所有和模式匹配的子串,不重疊的放入一個列表,一個子串都找不到就返回空列表[]
import redef findall(pattern , string) :x = re.findall(pattern , string)print(x)findall("scy" , "abcd")findall("scy" , "scy")findall("scy" , "abcscy")findall("scy" , "abcscydefscy")findall("scy.{2}scy" , "scyascyscyabscybbdkkjscy8yscy")
5、re.finditer()函數
re.finditer()函數的格式:
re.finditer(pattern , string , flags = 0)
查找字符串中每個符合匹配對象的子串(不重疊),每個子串對應一個匹配對象,返回匹配對象的序列(可調用迭代器)
(迭代器:迭代器是一個根據具體參數來進行抽象操作的行為,比如我們我一籃子水果,我們想把每個水果拿出來檢查以下,而迭代器就相當于水果分發器,把水果取出來,交給你)
例子:
import rea = "scy.{2}scy"b = "scyascyscyabscybbdkkjscy8yscy"for i in re.finditer(a , b) :print(i.group() , i.span())
輸出:
(如果發現沒有符合要求的子串,就無輸出)
6、迭代器
關于迭代器,迭代器是沒有group和span函數的,所以我們如果直接把finditer函數返回的東西和group函數結合使用是會報錯的!
下面是一個錯誤的例子:
import rea = "scy.{2}scy"b = "scyascyscyabscybbdkkjscy8yscy"c = re.finditer(a , b)
print(c.group() , c.span())
這個代碼會報錯,因為代碼中的c,是指finditer函數返回的迭代器本身,無法使用group函數,而上面正確的例子中那個i,因為在循環之中,每次循環i都會指向迭代器內一個新的且符合要求的匹配對象,對象中包含子串的一些信息!
我們上面那個正確的例子稍加修改:
import rea = "scy.{2}scy"b = "scyascyscyabscybbdkkjscy8yscy"for i in re.finditer(a , b) :print(i)
結果:
這個代碼就是生成迭代器中每個符合要求的匹配對象,然后里面包含子串及相關信息
這些符合要求的匹配對象的集合,把他放到一個容器中,就是迭代器!
7、re.sub()函數
re.sub()函數用于把目標子串替換成我們所要替換的內容:
基本格式:
re.sub(模式串,替換串,母串)
例子:
import restr = "adhba8bkwjciehwajbjhsduagbshuchaobcsdjk"
a = re.sub("a.b" , "00000" , str)
print(a)
輸出:
四、邊界符號
邊界符號用于指定字符的位置
我們下面會介紹幾個邊界符號:
?
邊界符號 | 作用 |
\A | 表示字符串的左邊界,及要求從此處往左不能有任何字符 |
\Z | 表示字符串的右邊界,及要求從此處往右不能有任何字符 |
^ | 與\A同,但多行匹配下還可以表示一行文字的左邊界 |
$ | 與\Z同,但多行匹配下還可以表示一行文字的右邊界 |
\b | 表示此處是單詞的左邊界或右邊界,即不可是單詞字符 |
\B | 表示此處不能是單詞的左邊界或右邊界,即必須是單詞字符 |
邊界字符和上面那些范圍符號一樣,都只是一個或兩個單獨的字符不是和\n一樣是一個字符!
五、分組
分組是正則表達式中很重要的一個概念,我們在Python的正則表達式中會用()來表達,一個括號的表達式是一個分組,多個分組按左括號,從左到右的順序從1開始編號
例子:
import rezs = "(((abc*)d)e)"
str = "abcdefgh"
a = re.match(zs , str)
print(a.group())
print(a.group(0)) #group(0)等價于group()
print(a.group(1))
print(a.group(2))
print(a.group(3))
print(a.groups())
輸出:
我們可以在分組的右面通過分組的編號來引用該分組匹配的字符串:
import rezs = r"(((abc*)d)e)\3"
str = "abcdeabccccfgh"
a = re.match(zs , str)
print(a.group())
這里的\3引用的就是(abc*),而(abc*)在前面得到是abc,所以\3就是abc
結果:
分組作為一個整體,后面可以跟量詞
例子:
import rezs = r"(((abc*)+d)e)"
str = "abcabcabcabcdecfgh"
a = re.match(zs , str)
print(a.group())
輸出:
(上述這些代碼如果沒有遇到能匹配的子串,就會報錯,建議放到try里面)
以上就是Python正則表達式(一)的全部內容:)