一:生成器:Generator,可以了解為是一種一個函數産生一個疊代器,而疊代器裡面的資料是可以通過for循環擷取的,那麼這個函數就是一個生成器,即生成器是有函數生成的,建立生成器使用()表示,比如g = (x for x in range(10)),那麼即建立一個名稱為g的生成器,,如果外層是[]則表示是生成一個清單,生成器生成的序列可以使用next()方法擷取其中的值:
1.__next__()方法擷取序列中的值:
g1 = (x for x in range(3))print(type(g1),"print(type(g1)的結果")print(g1,"print(g1)的結果")print(g1.__next__())print(g1.__next__())print(g1.__next__())
執行結果; print(type(g1)的結果 at 0x101b817d8> print(g1)的結果
01
2如果是[]表示,則在使用__next__()取值的時候儲存,會提示沒有__next__()方法:
g1= [x for x in range(3)]print(g1.__next__())
執行結果:
Traceback (most recent call last):
File"/Users/zhangshijie/PycharmProjects/S12-Python3/day4/11.py", line 5, in
print(g1.__next__())
AttributeError:'list' object has no attribute '__next__'
_next__()擷取序列中的值
2.__next__()擷取檔案中的行:
deffunc():
with open("test.txt") as f:try:whileTrue:
line= next(f) #每次讀取一行,會自動換下一行
print(line,end='')exceptStopIteration:print("\n已經讀取檔案完成-->StopIteration執行")
func()
執行結果:globallog127.0.0.1local2
daemon
maxconn256log127.0.0.1local2 info
defaults
logglobalmode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
option dontlognull
listen stats :8888stats enable
stats uri/admin
stats auth admin:1234已經讀取檔案完成-->StopIteration執行
__next__()擷取檔案中的行
3.如果生成器生成的序列中的值已經全部被__netx__()方法取出,但是後續還要擷取資料的話,則會抛出StopIteration異常,如下:
g1 = (x for x in range(3))print(type(g1),"print(type(g1)的結果")print(g1,"print(g1)的結果")print(g1.__next__())print(g1.__next__())print(g1.__next__())print(g1.__next__())print(g1.__next__())
執行結果: print(type(g1)的結果 at 0x101b817d8> print(g1)的結果
01
2 #在執行完成這一條資料的擷取之後就報異常了
Traceback (most recent call last):
File"/Users/zhangshijie/PycharmProjects/S12-Python3/day4/test.py", line 201, in
print(g1.__next__())
StopIteration
StopIteration 異常
4.解決異常的辦法:
g1 = (x for x in range(3))for i ing1:try:print(type(g1),"print(type(g1)的結果")print(g1,"print(g1)的結果")print(g1.__next__(),"1")print(g1.__next__(),"2")print(g1.__next__(),"3")print(g1.__next__(),"4")print(g1.__next__(),"5")except StopIteration: #當捕獲到指定的異常之後則執行以下的指令
print("資料已經或完成了")
執行結果: print(type(g1)的結果 at 0x1012817d8> print(g1)的結果1 1
2 2資料已經或完成了
捕獲StopIteration
二:疊代器,是一個可使用for循環周遊每一個元素的可疊代對象,之前學過的可疊代對象(Iterable)有以下幾種,一是常見的資料類型,如清單list,元組tuple,字典dict,集合set,字串ztr等,二是生成器(generator)和yield的生成器方法(generator function),如果想知道一個對象是否是可疊代對象(Iterable),如:
1、使用isinstance()方法檢視指定對象是否是可疊代對象,如:
from collections importIterableprint(isinstance((10),Iterable),"10是否可疊代對象")print(isinstance([],Iterable),"[]是否可疊代對象")print(isinstance((),Iterable),"()是否可疊代對象")print(isinstance({},Iterable),"{}是否可疊代對象")print(isinstance("abcd",Iterable),"字元串abcd是否可疊代對象")print(isinstance((x for x in range(10)),Iterable),"for生成的序列是否可疊代對象")
執行結果:
False 10是否可疊代對象
True []是否可疊代對象
True ()是否可疊代對象
True {}是否可疊代對象
True 字元串abcd是否可疊代對象
True for生成的序列是否可疊代對象
isinstance判斷對象是否可疊代對象
2.使用isinstance()方法檢視指定對象是否是疊代器,如:
from collections importIteratorprint(isinstance((10),Iterator),"10是否疊代器")print(isinstance([],Iterator),"[]是否疊代器")print(isinstance((),Iterator),"()是否疊代器")print(isinstance({},Iterator),"{}是否疊代器")print(isinstance("abcd",Iterator),"字元串abcd是否疊代器")print(isinstance((x for x in range(10)),Iterator),"for生成的序列是否疊代器")
g1= (x * x for x in range(10))print(isinstance(g1,Iterator),"g1生成的序列是否疊代器")
執行結果:
False 10是否疊代器
False []是否疊代器
False ()是否疊代器
False {}是否疊代器
False 字元串abcd是否疊代器
True for生成的序列是否疊代器
True g1生成的序列是否疊代器
isinstance判斷對象是否疊代器
3.疊代器(Iterator)和疊代對象(Iterable)的差別:
1、可以從其中通過for循環擷取資料的都是可疊代對象(Iterable)
2、可以通過next()方法擷取資料的對象都是疊代器(Iterator)
3、疊代器隻是在通過使用next()方法擷取資料的時候才會計算,是以比可疊代對象效率更高并在記憶體使用率更低,因為可疊代對象是一次生成。
4、疊代器執行過程中無法後退到上一個或傳回到指定的元素,其隻能通過next()方法繼續往前執行
5、for循環的readlines方法是一次讀取所有行并将所有行放在一個清單當中,read()方法是讀取所有内容到記憶體并儲存為字元串格式
三:遞歸函數:
函數的内部可以調用其他的函數,但是如果這個函數的内部在執行的時候調用了函數自身,那麼這個函數就是遞歸函數,是以遞歸函數一定是在函數裡實作的,即先聲明一個函數然後在函數内部中調用自己,遞歸函數需要有一個明确的退出接口,因為如果不設定退出接口則會進入無限循環調用的場景,最終可能會導緻記憶體用盡等場景:
1.建立一個簡單的遞歸函數:
deffunc(num):print(num)if num > 1: #先判斷num的值大于1才繼續執行
func(num -1) #在函數的原基礎之上執行數值減1
func(10) #傳遞的值為10
執行結果:10
9
8
7
6
5
4
3
2
1
簡單遞歸函數
2.使用遞歸函數計算斐波拉契(Fibonacci)算法
斐波拉契(Fibonacci)算法,即書第一個和第二個數值之外,這兩個數值之後的任意一個數都是有前兩位數值相加得出的,比如:0,1, 1, 2, 3, 5, 8, 13, 21, 34,55 ...這種結果如果用清單和for循環很不好計算,而且生成清單會生成很多用不到的數值,但是使用函數計算就比較簡單了。
遞歸函數計算斐波那契算法的方法如下:
deffunc(num):
x= 0 #定義三個變量
y =0
z= 1
while x < num: #假如x的值小于函數調用的時候傳遞的num的數值
print(z) #列印z的結果
y,z = z,y + z #将y的等于z的值,z的值等于y+z的值,即完成了後面的一個數的值是有前兩個數值相加的結果
x += 1 #然後将x的值自增1
print("每次相加分割線--------->")return z #将最終z的值傳回給函數名,最後函數的值就等于z
print(func(30))
執行結果:1每次相加分割線--------->
1每次相加分割線--------->
2每次相加分割線--------->
3每次相加分割線--------->
5每次相加分割線--------->
8每次相加分割線--------->
13每次相加分割線--------->
21每次相加分割線--------->
34每次相加分割線--------->
55每次相加分割線--------->
89每次相加分割線--------->
144每次相加分割線--------->
233每次相加分割線--------->
377每次相加分割線--------->
610每次相加分割線--------->
987每次相加分割線--------->
1597每次相加分割線--------->
2584每次相加分割線--------->
4181每次相加分割線--------->
6765每次相加分割線--------->
10946每次相加分割線--------->
17711每次相加分割線--------->
28657每次相加分割線--------->
46368每次相加分割線--------->
75025每次相加分割線--------->
121393每次相加分割線--------->
196418每次相加分割線--------->
317811每次相加分割線--------->
514229每次相加分割線--------->
832040每次相加分割線--------->
1346269
函數計算斐波那契算法
隊規算法可用于解決以下問題:
資料的定義是按遞歸定義的,比如清單,Fibonacci函數)
問題解法可以安裝按遞歸算法實作。(回溯)
資料的結構形式是按遞歸定義的。(比如樹的周遊,圖的搜尋)
遞歸的缺點:遞歸算法解題的運作效率較低。在遞歸調用的過程當中系統為每一層的傳回點、局部量等開辟了棧來存儲。遞歸次數過多容易造成記憶體棧溢出等。
函數傳回值:
deffunc1(num):return 3,6,9,num #多個值傳回給函數名
print(func1(10))
a= list(func1(10))print(a)
a,b,c,num= func1(11) #對函數傳回值進行拆包,将傳回值指派給多個變量
print(a,"a從func1(11)執行結果擷取到的值")print(b,"b從func1(11)執行結果擷取到的值")print(c,"c從func1(11)執行結果擷取到的值")print(num,"num從func1(11)執行結果擷取到的值")
執行結果:
(3, 6, 9, 10) #函數傳回值預設是元組
[3, 6, 9, 10] #可以将元組轉換為清單進行增删元素
3 a從func1(11)執行結果擷取到的值6 b從func1(11)執行結果擷取到的值9 c從func1(11)執行結果擷取到的值11 num從func1(11)執行結果擷取到的值
函數傳回值拆包
四:裝飾器:
裝飾器本身是一個函數,是為了不改變其他函數的代碼和使用者調用方法的情況下其他函數添加之前沒有的功能,如下是一個簡單的裝飾器:
1.裝飾器的函數是傳遞固定參數:
deflogin(func):definner(arg):print("通過驗證")
func(arg)#傳回的是func形參的記憶體位址,這裡func的實參是tc,是以傳回了tc的記憶體位址
returninner
@logindeftv(name):print("歡迎%s登入tv界面" %name)
tv= login(tv) #将tv作為函數login函數的執行參數傳遞過去
tv("jack")
View Code
2.裝飾器的函數是傳遞動态參數:
def login(func): #此時的func等于tv的記憶體位址,而tv執行的時候需要兩個參數*arg,**abc
def inner(*arg,**abc):print("通過驗證")return func(*arg,**abc) #傳回的是func形參的記憶體位址,這裡func的實參是tc,是以傳回了tc的記憶體位址
return inner #傳回的是
@logindef tv(*arg,**abc):print("歡迎登入tv界面")
tv= login(tv) #将tv作為函數login函數的執行參數傳遞給login函數
tv("jack","pass=123")
執行結果:
通過驗證
通過驗證
歡迎登入tv界面
執行流程:1.進入到第一行代碼login(func)放入記憶體,不執行函數内部2.到裝飾器@login3.傳回到login,即第一行,因為對函數進行了調用,将login重新定義為tv =login(tv),即把被裝飾的函數做為參數傳遞給裝飾器并再指派給函數本身4.進入login内部,執行第一層函數inner,放入記憶體5.inner的執行結果是inner得到記憶體位址,得到此位址是為了不做驗證,不然裝飾器一被調用就通過了驗證6.執行tv =login(tv),将函數tv作為參數傳遞給函數login,而login是個裝飾器7.傳回到第一行login(func)8.執行内部函數inner9.将innter函數放在記憶體10.執行tv("jack","pass=123")login(func),将實參傳遞給inner11.進入到inner。此時的innter的arg是arg:("jack","pass=123") abc={}12.return func(*arg,**abc)的結果給inner13.退回到inner函數14..return func(*arg,**abc),此時的值已經給了inner15.執行裝飾器@login16.列印歡迎界面
View Code
3.給裝飾器傳遞參數:
def Before(request,kargs): #第一步将函數放進記憶體#第六步,在裝飾器之後執行函數#第十步執行裝飾器的内部函數的參數,這次是一個外部函數
print('before') #十一部,print結果
def After(request,kargs): #第二部放進第二個記憶體#十二部執行另一個函數
print('after')def Filter(before_func,after_func): #第三部按照順序放進第三個函數#第五步執行裝飾器,并将裝飾器的參數執行,本次為兩個函數
def outer(main_func): #第六到裝飾器裡面的函數
#第八步從return傳回到這個函數
defwrapper(request,kargs):#第九步執行傳回對應的函數,得到request,kargs的值
before_result =before_func(request,kargs)if(before_result !=None):returnbefore_result;
main_result=main_func(request,kargs)if(main_result !=None):returnmain_result;
after_result=after_func(request,kargs)if(after_result !=None):returnafter_result;returnwrapperreturn outer #第七部,裝飾器裡面的第一個函數傳回這個函數内部的函數名,這個函數名是個未執行的記憶體位址
#第十部
@Filter(Before, After)#第四部到裝飾器界面
defIndex(request,kargs):print('index')
Index("aa","bb")
執行結果:
before
index
after
帶參數的裝飾器
五:python正規表達式基本方法:
正規表達式是處理字元串的一種工具,在很多語言裡都支援,它是通過一定的規則文法,去指定的元素中比對、查找和替換等操作字元串,在python裡面是一個子產品叫做re,通過import導入即可使用,re子產品在python1.5版本添加,以下是是python 3.5.1當中的re子產品常用方法:
1.compile(pattern, flags=0):将字元串轉形式的正規表達式編譯為Pattern對象,用于将常用的字元串轉換成Pattern對象便于以後經常比對這些字元串,然後傳回RegexObject對象,最後可以通過RegexObject對象調用match()和search()方法,如:
importre
reb= re.compile(r'abc') #将要比對的字元串提前編譯好,利于以後調用
rec = reb.match("abcd") #在abcd中比對編譯好的abc
ifrec:print(rec)print(rec.group(),"第一組比對成功")else:print("第一組匹為比對成功")
rea= re.compile("abc")
red= rea.match("ab")ifred:print(red.group(),"第二組比對成功")else:print("第二組未比對成功")
執行結果:<_sre.sre_match object span="(0," match="abc"> #為使用group的結果,是以要檢視比對到的字元串要使用group檢視
abc 第一組比對成功
第二組未比對成功
compile
group():傳回被正規表達式比對成功的字元串
start():傳回被正規表達式比對成功字元串的開始下标位置
end():傳回被正規表達式比對成功的字元串結束的下标位置
snap():同時傳回開始和結束位置
importre
s1= re.search("1","2nk11askd1") #search會從頭到位比對全部字元串當中是否有指定的字元串出現,在任意位置比對成功都算成功
ifs1:print(s1.group(),"第一組比對成功")else:print("s1比對失敗")print()
s2= re.search("10","11034a10bc") #在中間和結果比對成功都算是比對成功的
ifs2:print(s2.group(),"第一組比對成功")print(s2.start(),"start傳回開始的索引")print(s2.end(),"end傳回結束的索引")print(s2.span(),"span傳回開始和結束的索引")else:print("s2比對失敗")
2.escape(pattern):python3.4 新加,對字元串中的非字母數字進行轉義,即對特殊字元和特殊符号做轉義,在其前方加上反斜線\,如:
importreprint(re.escape("www.test.com,#mail,[email protected]"))
執行結果:
www\.test\.com\,\#mail\,xxx\@xx\.com #在标點符号、特特殊字元前自動加上反斜線進行轉義
3.findall(pattern, string, flags=0):以傳回清單顯示所有可以比對到的結果,與search不同的是findall傳回的是比對到的所有結果,即傳回的是不固定數量的結果,如:
importre
s1= re.findall("123","abc123abc123xy1234") #隻比對123
print(s1)
執行結果:
['123', '123', '123']importre
s1= re.findall("12\d+","abc123abc123xy1234") #比對12後面有一個或多個數值
print(s1)
執行結果:
['123', '123', '1234']
findall
4.finditer(pattern, string, flags=0):比對所有字元串,并傳回一個疊代器,需要用for循環擷取其中的值,如:
importre
a1= re.compile("bc") #編譯好比對對象,之比對字元串bc
s1 = a1.finditer("abc123abc123xy1234")for i ins1:print(i.group())
執行結果:
bc
bc#第二個bc是在字元串的中間也可以比對到
View Code
5.fullmatch(pattern, string, flags=0):判斷比對的字元串和目标字元串是否完全一緻,是傳回比對group()成功的字串,否傳回None,如:
importre
s1= re.fullmatch("password","password")ifs1:print(s1.group(),"比對成功")else:print("比對失敗")
執行結果:
password 比對成功#字元串完整比對成功
6.match(pattern, string, flags=0):match隻從開頭比對第一個字元串,第一個未比對就不再繼續向後比對,即使後面可以比對到也不繼續比對,其隻從第一位比對指定的字元串,如果連續比對上算成功,如果有一個比對不上即傳回比對失敗并傳回None:
在python術語中,主要有兩種方法完成模式比對,搜尋(searching)和比對(matching),搜尋是在字元串中的任意位置搜尋比對的模式,而比對是指判斷一個字元串是否從起始位置就全部比對或部分比對的某個模式,搜尋是通過search()函數或方法實作,而比對是調用match()函數或方法實作的:
importre
s1= re.match("1","12nkaskd1") #match隻從開頭比對第一個字元串,第一個未比對就不再繼續向後比對,即使後面可以比對到也不繼續比對
ifs1:print(s1.group(),"第一組比對成功")else:print("s1比對失敗")
s2= re.match("10","12034abc") #即使後面有0也不比對,其隻從第一位比對指定的字元串,如果連續比對上算成功,如果有一個比對不上即傳回比對失敗
ifs2:print(s2.group(),"第一組比對成功")else:print("s2比對失敗")
執行結果;
7.purge():清空緩存中的正規表達式
importre
s1= re.compile("password+=")print(re.compile(s1))print(re.purge())
執行結果:
re.compile('password+=')
None
8.search(pattern, string, flags=0):search會從頭到位比對全部字元串當中是否有指定的字元串出現,在任意位置比對成功都算成功,傳回的是比對成功的字元串:
search與findall的不同:
search是傳回到的一個比對到的結果,即使字元串當中有多個比對結果也隻傳回一個,而且是傳回的字元串格式
findall是傳回的所有比對結果,并将結果附加在一個清單當中
importre
s1= re.search("1","2nkaskd1") #search會從頭到位比對全部字元串當中是否有指定的字元串出現,在任意位置比對成功都算成功
ifs1:print(s1.group(),"第一組比對成功")else:print("s1比對失敗")
s2= re.search("10","12bn1034abc") #在中間和結果比對成功都算是比對成功的
ifs2:print(s2.group(),"第一組比對成功")else:print("s2比對失敗")
執行結果:1第一組比對成功10 第一組比對成功
#######search與findall的不同:
importre
s1= re.findall("ab","2nabkabcddopaoab") #search會從頭到位比對全部字元串當中是否有指定的字元串出現,在任意位置比對成功都算成功
ifs1:print(s1,"第一組比對成功")else:print("s1比對失敗")
s2= re.search("10","10102bn1034ab10c") #在中間和結果比對成功都算是比對成功的
ifs2:print(s2.group(),"第一組比對成功")else:print("s2比對失敗")
執行結果:
['ab', 'ab', 'ab'] 第一組比對成功,findall是傳回的所有比對結果,并将結果附加在一個清單當中10 第一組比對成功,search是傳回到的一個比對打牌的結果,即使字元串當中有多個比對結果也隻傳回一個,而且是傳回的字元串格式
9.split(pattern, string, maxsplit=0, flags=0):split() 方法在用于在正規表達式中将字元串按照指定的分隔符進行切分,切分後将傳回清單,方法同字元串的 split() 方法相似但提供更多的定界符,如:
importre
a1= re.compile(r"\(")
s1= a1.split("1+10-(10*3)") #search會從頭到位比對全部字元串當中是否有指定的字元串出現,在任意位置比對成功都算成功
print(s1)
執行結果:
['1+10-', '10*3)'] #傳回一個清單,以(對原字元串進行切分
10.sub(pattern, repl, string, count=0, flags=0):
importre
a1= re.compile(r"jack") #提前編譯正常表達式,指定替換的字元串為jack
s1 = a1.sub("tom","name is jack,name is jack,name is jack",count=2) #sub後面跟随将jack替換的目标字元串,和在哪裡替換,可選參數count指定替換參數,預設為全部替換
s2 = a1.sub("tom","name is jack,name is jack,name is jack") #不指定替換次數
print(s1,"指定了2次替換")print(s2,"未指定替換次數")
執行結果:
nameis tom,name is tom,name is jack #指定了2次替換,超出次數一行将不再替換
name is tom,name is tom,name is tom 未指定替換次數
11.subn(pattern, repl, string, count=0, flags=0):subn() 方法類似于sub方法做字元串替換,但是傳回的結果是替換後的一個元組,元組的前部分是替換後的結果,後部分是替換的次數,如:
importre
a1= re.compile(r"jack") #提前編譯正常表達式,指定替換的字元串為jack
s1 = a1.subn("tom","name is jack,name is jack,name is jack",count=2) #sub後面跟随将jack替換的目标字元串,和在哪裡替換,可選參數count指定替換參數,預設為全部替換
s2 = a1.subn("tom","name is jack,name is jack,name is jack") #不指定替換次數
print(s1,"指定了2次替換")print(s2,"未指定替換次數")
執行結果:
('name is tom,name is tom,name is jack', 2) 指定了2次替換
('name is tom,name is tom,name is tom', 3) 未指定替換次數
12.template(pattern, flags=0):和
importre
s1= re.template("21") #編譯好要比對的字串
print(s1.search("jack and tom is 21").group()) #對編譯好的字串進行比對
執行結果:21 #隻顯示找到的字串
六:正規表達式比對進階模式:
1.字元串比對:
. :比對任意單個字元,(換行符除外):
importreprint(re.match("2.","1+2-3*2+(4-4+1/3)")) #matc從0個元素比對,一次成功即成功,不成功則失敗并傳回None,matc傳回的是直接比對結果,不需要使用group() 檢視比對到的内容
執行結果:
None#################
importreprint(re.search("2.","1+2-3*2+(4-4+1/3)").group()) #search比對成功後隻顯示一個比對結果,而且需要使用group檢視比對到的結果
執行結果:2-
##################
importreprint(re.findall("1.","1+2-3*2+(4-4+1/3)")) #findall 會在整個字元串比對,并以清單結果顯示比對到的所有的結果
執行結果:
['1+', '1/']
^ :從字元串的頭部開始比對,可以比對是否以指定字元開頭:
importreprint(re.findall("^1","1+2-3*2+(4-4+1/3)")) #search比對成功後隻顯示一個比對結果,而且需要使用group檢視比對到的結果
執行結果:
['1']
$ :比對字元串的結束,可以比對是否已指定字元串結束:
importreprint(re.findall("1$","1+2-3*2+(4-4+1/3)-1"))print(re.findall("1$","1+2-3*2+(4-4+1/3)-2"))#比對是否已指定字元串結尾,是傳回比對結果.否傳回空清單
執行結果:
['1']
[]
* :比對前一個字元出現了0次或多次,即前面的字元可以沒有比對到也可以有無數個,這種操作符也稱為Kleene(閉包操作):
importreprint(re.findall("a*","1+a+b-2"))#比對是否已指定字元串結尾,是傳回比對結果.否傳回空清單
執行結果:
['', '', 'a', '', '', '', '', ''] #傳回清單形式的結果,為比對帶的元素用空字串表示
+ :比對前一個元素出現一次或多次,即至少要有一次,也可以有無數次,也被稱為正閉包操作:
importreprint(re.findall("a+","1+aaaba+b-2"))#比對是否已指定字元串結尾,是傳回比對結果.否傳回空清單
執行結果:
['aaa', 'a']
? :比對前一個字元出現0次或1次,即可以1個也沒有,也可以有1個,但是後面就不會比對了,因為隻會比對一個沒有有一個,不負責比對兩個:
importreprint(re.findall("a?","1+aaaba+b-2"))#比對是否已指定字元串結尾,是傳回比對結果.否傳回空清單
執行結果:
['', '', 'a', 'a', 'a', '', 'a', '', '', '', '', ''] #單獨比對每個元素,未能比對成功的元素以空字串表示
{N}:比對前面的表達式指定次數,即強制比對多少次:
importreprint(re.findall("a{3}","1+aaaba+b-2"),"#指定前面的字元比對多少次,比對結果放在清單當中")print(re.findall("a{4}","1+aaaba+b-2"),"#指定前面的字元比對多少次,超出範圍後抛出空清單")
執行結果:
['aaa'] #指定前面的字元比對多少次,比對結果放在清單當中
[] #指定前面的字元比對多少次,超出範圍後抛出空清單
{M,N}: 比對前面的字元出現M-N次
importreprint(re.findall("a{1,3}","1+aaaba+b-2"),"#指定前面的字元比對多少到多少次,比對結果分開放在清單當中")print(re.findall("a{1,10}","1+aaaba+b-2"),"#指定前面的字元比對多少到多少次,比對結果分開放在清單當中,超出比對範圍不報錯")
執行結果:
['aaa', 'a'] #指定前面的字元比對多少次,比對結果放在清單當中
['aaa', 'a'] #指定前面的字元比對多少次,超出範圍後抛出空清單
[xxx] :比對字元串當中的任意一個字元:
importreprint(re.findall("a[abc]","1+aabbaba+b-2"),"比對中括号當中的任意一個字元,即a後面可以是a可以是b也可以是c,中括号裡的字元之間是或關系")print(re.findall("b[abc]","1+babababab"),"比對中括号當中的任意一個字元,字元是或關系")
執行結果:
['aa', 'ab'] 比對中括号當中的任意一個字元,字元是或關系
['ba', 'ba', 'ba', 'ba'] 比對中括号當中的任意一個字元,字元是或關系
[x-y]:比對出現在中括号裡的任意一個字元:
importreprint(re.findall("a[a-z]","1+aabbaba+b-2"),"比對a-z當中的任意一個字元")print(re.findall("b[b-d,f-z]","abacdbebz"),"比對中括号當中b-d和f-z當中的字元,即把a和e不比對,如此比對則前方的ba和be都沒有比對到")
執行結果:
['aa', 'ab'] #比對a-z當中的任意一個字元
['bz'] #比對中括号當中b-d和f-z當中的字元,即把a和e不比對,如此比對則前方的ba和be都沒有比對到
[^x-y]:取反,凡是出現在裡面的字元都不進行比對:
importreprint(re.findall("a[^c-z]","1+aabbaba+b-2"),"比對a-z當中的任意一個字元")print(re.findall("b[^b-d,f-z]","abacdbebz"),"與上次完全相反,這次出現在裡面的不比對,不出現的卻被比對,本次隻比對a和e")
執行結果:['aa', 'ab', 'a+'] 比對a-z當中的任意一個字元
['ba', 'be'] 與上次完全相反,這次出現在裡面的不比對,不出現的卻被比對,本次隻比對a和e
[^xy]:不比對出現在中括号裡面的單個字元:
importreprint(re.findall("a[^bcd]","1+aabbaba+b-2"),"a後面凡是出現b或c胡或d都不比對")print(re.findall("b[^b,d-z]","abacdbcbebbz"),"b後面出現b,d-z的字元不比對")
執行結果:
['aa', 'a+'] a後面凡是出現b或c胡或d都不比對
['ba', 'bc'] b後面出現b,d-z的字元不比對
():對表達式進行分組:
importre
s1= re.match("(a(b)c)","abc") #對比對進行分組,
print(s1.group(1),"分組1")print(s1.group(2),"分組2")print(s1.groups(),"所有分組")
執行結果:
abc 分組1
b 分組2
('abc', 'b') 所有分組
2.特殊字元比對:
\d:比對任何數字,和0-9效果一緻:
importreprint(re.search("\da","abc1a").group()) #比對任何一個數字後面跟了一個a
執行結果:
1a
\D:和\d完全相反,比對任何非數字
importreprint(re.search("\Da","[email protected]").group()) #查找特殊字元後面帶a的
執行結果:
@a#比對到的特殊字元
\w:比對任何數字字母字元,同等于[0-9][a-z][A-Z]:
importreprint(re.search("\wa","[email protected]").group()) #比對任何一種字母數字和字元後後面帶a的
執行結果:
wa#比對到的wa
\W:和\w完全相反,取[0-9][a-z][A-Z]以外的特殊字元:
importreprint(re.findall("\Wa","[email protected]"),"\W隻會比對數字和大小寫字母以外的特殊字元")print(re.findall("\Da","[email protected]"),"\D會比對除數字以外的其他字元,包括字母和特殊字元")
執行結果:
['@a'] \W隻會比對數字和大小寫字母以外的特殊字元
['ra', '@a'] \D會比對除數字以外的其他字元,包括字母和特殊字元
\s:比對任何空白字元,等于比對\n \t \r \v \f:
importreprint(re.findall("\s","w [email protected]"),"\s比對空格")print(re.findall("\s","wrabc 1!1@\na"),"\s比對空格和換行符\n")
執行結果:
[' '] \s比對到的空格元素
[' ', '\n'] \s比對空格和換行符和空格
\S:與\s相反,比對空白字元\n \t \r \v \f以外的字元
importreprint(re.findall("\S","w [email protected]"),"\S比對空白符以外的字元,中間的空格給忽略了")print(re.findall("\S","wrabc 1!1@\na"),"\S比對空白字元以外的字元,空格和\n給忽略了")
執行結果:
['w', 'r', 'a', 'b', 'c', '1', '!', '1', '@', 'a'] \S比對空白符以外的字元,中間的空格給忽略了
['w', 'r', 'a', 'b', 'c', '1', '!', '1', '@', 'a'] \S比對空白字元以外的字元,空格和
給忽略了
\b:比對單詞邊界:
importreprint(re.findall(r"oy\b","tom jack is a boy!"),"比對右側是否單詞邊界,即有空格或其後面沒有單詞了,boy是最後一個單詞")print(re.findall(r"om\b","tom jack is a boy!"),"比對右側是否單詞邊界,即有空格或其後面沒有單詞了,om是tom,右側是空格")print(re.findall(r"\bom","tom jack is a boy!"),"om是tom,om的左側還有一個t是以其左側不是單詞邊界")
執行結果:
['oy'] 比對右側是否單詞邊界,即有空格或其後面沒有單詞了,boy是最後一個單詞
['om'] 比對右側是否單詞邊界,即有空格或其後面沒有單詞了,om是tom,右側是空格
[] om是tom,om的左側還有一個t是以其左側不是單詞邊界
\B:與\b相反,比對非單詞邊界,即這個單詞不是以此開頭的:
importreprint(re.findall(r"oy\B","tom jack is a boy!"),"oy右側是單詞邊界,是以不會比對上")print(re.findall(r"\Bom","tom jack is a boy!"),"om左側不是單詞邊界,是以可以比對成功")print(re.findall(r"om\B","tom jack is a boy!"),"om右側是邊界,是以不會比對成功")
執行結果:
[] oy右側是單詞邊界,是以不會比對上
['om'] om左側不是單詞邊界,是以可以比對成功
[] om右側是邊界,是以不會比對成功
\nn:比對已經儲存的子組:
比對手機号:
importre
a= "mail:[email protected],TEL:18600033300"b= "email:[email protected]"
print(re.findall(r"\d[0-9]{10}",a))print(re.findall(r"\d[0-9]{10}",b))
執行結果:
['18600033300']
[]
比對郵箱位址:
importre
a= "mail:[email protected],TEL:18600033300"b= "email:[email protected]"
print(re.findall("\w+@\w+\.*\w+\.com",a)) #\w+\.* 比對*前面的字元0次或多次,本次比對三級域名郵箱
print(re.findall("\w+@\w+\.*\w+\.com",b)) #本次比對兩級域名的郵箱
執行結果:
['[email protected]']
['[email protected]']
match隻從開頭進行完整比對,頭部比對成功才算成功,search相當于全行比對,任意位置比對成功都算成功,兩種方法傳回的是比對到的對象,要使用group檢視對象裡面的結果
findall傳回的是所有結果的一個清單,不需要使用group即可看到結果,也可以使用for循環周遊每一個元素