概述
正則表達式是一個特殊的字符序列,它常常用於檢查是否與某種模式匹配。第八節課主要從以下幾方面介紹了Python正則表達式的用法。
(1)re模塊的使用
(2)字符匹配、數量表示、邊界表示
(3)正則表達式的高級用法
(4)貪婪與非貪婪模式
re模塊:Regular Expression
(一)match(正則表達式,待匹配字符串)
(1)採用從左向右逐項匹配,從起始位置起。
(2)用於正則匹配檢查,如果“待匹配字符串”能夠匹配“正則表達式”,則match方法返回匹配對象,否則返回None
import re #導入re模塊
#從起始位置開始匹配
rs = re.match("51cto", "51cto.com")
print(rs.group())
#沒有從起始位置開始匹配。沒有字符被匹配上。
rs = re.match("com", "51cto.com")
print(rs)
運行結果:
51cto
None
(二)group(num = 0)方法 :
(1)默認用來返回字符串的匹配部分
(2)匹配的整個表達式的字符串,group() 可以一次輸入多個組號(),在這種情況下它將返回一個包含那些組所對應值的元組。
#(163|outlook|qq)是第一組,索引爲1;(com|cn)是第二組,索引爲2
rs = re.match("\w{3,10}@(163|outlook|qq)\.(com|cn)$","[email protected]")
print(rs.group()) #默認返回字符串的匹配部分
print(rs.group(1))
print(rs.group(2))
print(rs.groups()) #返回一個包含所有小組字符串的元組,從 1 到 所含的小組號
運行結果:
[email protected]
163
com
('163', 'com')
字符匹配、數量表示、邊界表示
(一)單字符匹配
(1). 匹配除"\n"之外的任意單個字符
import re
rs = re.match(".", "a")
print(rs.group())
rs = re.match(".", "1")
print(rs.group())
rs = re.match("...", "abc") #多個字符
print(rs.group())
rs = re.match(".", "\n")
print(rs)
運行結果:
a
1
abc
None
(2)\s:匹配任意空白字符,如空格,製表符“\t”,換行符“\n”
import re
rs = re.match("\s", "\t")
print(rs)
rs = re.match("\s", "\n")
print(rs)
rs = re.match("\s", " ")
print(rs)
(3)\S:匹配任意非空字符;和\s模式相反
rs = re.match("\S", "\t")
print(rs)
rs = re.match("\S", "abc") #匹配單個字符,從起始位置
print(rs.group())
運行結果:
None
a
(4)[ ]匹配[ ]中列舉的字符
rs = re.match("[Hh]", "hello")
print(rs.group())
rs = re.match("[Hh]", "Hello")
print(rs.group())
rs = re.match("[0123456789]", "32")
print(rs.group())
rs = re.match("[0-9]", "3")
print(rs.group())
運行返回結果:
h
H
3
3
其他單字符匹配用法不一一列舉。
(二)數量表示
(1)* 出現次數 n >= 0
import re
rs = re.match("1\d*", "1234567") #匹配規則:起始是1,接着數字[0-9]出現任意次
print(rs.group())
rs = re.match("1\d*", "1234567abc")
print(rs.group())
運行結果:
1234567
1234567
(2)+ 出現次數n >=1
rs = re.match("\d+", "abc") #\d :起始是數字[0-9],數字出現至少一次
print(rs)
rs = re.match("\d+", "1abc")
print(rs.group())
運行結果:
None
1
(3){m}, {m,} 和 {m, n}
#{m} : 一個字符出現m次
rs = re.match("\d{3}", "123abc")
print(rs.group())
#{m,} :一個字符至少出現m次
rs = re.match("\d{1,}", "123467abc") #等價於+至少一次
print(rs.group())
#{m,n} :一個字符出現m到n次
rs = re.match("\d{0,1}", "1abc") #等價於?至多一次
print(rs.group())
運行結果:
123
123467
1
(4)\轉義字符
在Python裏,\是轉義字符。其實在其他語言裏,\也是轉義字符。反斜槓\後面的特殊字符,比如換行符\n,正則表達式中的單字符匹配. 等原樣打印出來
str1 = "hello\\world"
print(str1) #僅僅打印了一個反斜槓
#打印兩個反斜槓,如果是三個反斜槓,也是打印出兩個反斜槓
str2 = "hello\\\\world"
print(str2)
str3 = r"hello\\world" #原生字符:r"str"
print(str3)
#在正則表達式裏,如果要匹配字符串中的反斜槓,字符串中的一個反斜槓在正則表達式中就要四個反斜槓進行匹配。
rs = re.match("\w{5}\\\\\\\\\w{5}", str3)
print(rs.group())
rs = re.match(r"\w{5}\\\\\w{5}",str3)
print(rs.group())
運行結果:
hello\world
hello\\world
hello\\world
hello\\world
hello\\world
(三)邊界表示
(1)字符串與單詞邊界:$結尾
#字符.沒有被認爲是一般字符
rs = re.match("\w{3,10}@163.com","hello_124@163mcom")
print(rs.group())
#轉義字符對符號.起作用
rs = re.match("\w{3,10}@163\.com$","[email protected]")
print(rs.group())
運行結果:
hello_124@163mcom
[email protected]
注意:第一個郵箱匹配實際是我們不期望的。但是它仍然被匹配成功,是因爲字符. 被當成單字符匹配了。所以我們需要加上轉義字符,讓. 被當成正常字符。
(2)匹配分組:()分組
rs = re.match("\w{3,10}@(163|outlook|qq)\.com$","[email protected]")
print(rs.group())
輸出結果:
[email protected]
索引可由自己制定,比如?P<g1>
html_str = "<head><title>python</title></head>"
rs = re.match(r"<.+><.+>.+</.+></.+>",html_str)
print(rs.group())
html_str2 = "<head><title>python</head></title>"
rs = re.match(r"<.+><.+>.+</.+></.+>",html_str2) #wrong to match
print(rs.group())
rs = re.match(r"<(.+)><(.+)>.+</\2></\1>",html_str) #\2 and \1 is an index
print(rs.group())
rs = re.match(r"<(?P<g1>.+)><(?P<g2>.+)>.+</(?P=g2)></(?P=g1)>",html_str)
print(rs.group())
運行結果:
<head><title>python</title></head>
<head><title>python</head></title>
<head><title>python</title></head>
<head><title>python</title></head>
正則表達式的高級用法:
(1)search():從左到右在字符串的任意位置搜索第一次出現匹配給定正則表達式的字符
#search()
rs = re.search("car","haha car carbal abcar carbal")
print(rs.group())
輸出結果:
car
(2)findall():在字符串中查找所有匹配成功的組,返回匹配成功的結果列表。
rs = re.findall("car","haha car carbal abcar carbal")
print(rs)
mail_str = "zhangsan:[email protected],li:[email protected]"
list = re.findall(r"(\w{3,20}@(163|qq)\.(com|cn))",mail_str)
print(list)
輸出結果:
['car', 'car', 'car', 'car']
[('[email protected]', '163', 'com'), ('[email protected]', 'qq', 'cn')]
(3)finditer():在字符串中查找所有正則表達式匹配成功的字符串,返回iterator迭代器。
mail_str = "zhangsan:[email protected],li:[email protected]"
itor = re.finditer(r"\w{3,20}@(163|qq)\.(com|cn)",mail_str)
for it in itor:
print(it.group())
輸出結果:
[email protected]
[email protected]
(4)sub()方法:將匹配到的數據使用新的數據替換
str = "java python c cpp java"
rs = re.sub(r"java","python",str)
print(rs)
輸出結果:
python python c cpp python
貪婪與非貪婪模式
(1)貪婪模式:儘可能的匹配更多的字符
(2)非貪婪模式:與貪婪模式相反
rs = re.findall(r"hello\d*","hello12345")
print(rs)
rs = re.findall(r"hello\d+","hello12345")
print(rs)
rs = re.findall(r"hello\d?","hello12345")
print(rs)
rs = re.findall(r"hello\d{2,}","hello12345")
print(rs)
rs = re.findall(r"hello\d{1,3}","hello12345")
print(rs)
print("----------------------------------")
rs = re.findall(r"hello\d*?","hello12345")
print(rs)
rs = re.findall(r"hello\d+?","hello12345")
print(rs)
rs = re.findall(r"hello\d??","hello12345")
print(rs)
rs = re.findall(r"hello\d{2,}?","hello12345")
print(rs)
rs = re.findall(r"hello\d{1,3}?","hello12345")
print(rs)
運行結果:
['hello12345']
['hello12345']
['hello1']
['hello12345']
['hello123']
----------------------------------
['hello']
['hello1']
['hello']
['hello12']
['hello1']
作業題
奶茶館價格結算系統優化:
1、 使用正則表達式判斷顧客輸入的手機號是否符合手機號設置規則:
1) 以數字 1 開頭
2) 第二位爲 3578 中的任意數字
3) 其餘 9 位爲 0-9 任意數字
2、 輸出手機號運營商,判斷規則:
移動運營商:手機號前三位爲 134、135、136、137、138、139
聯通運營商:手機號前三位爲 130、131、132、155、156、176
電信運營商:手機號前三位爲 133、153、173、177、180、181
def OutputPhoneProvider(str):
cell_phone_info = {"(134|135|136|137|138|139)":"China Mobile", "(130|131|132|155|156|176)":"China Unicom", "(133|153|173|177|180|181)":"ChinaTelecom"}
for key in cell_phone_info.keys():
field = re.match(key, str)
if field != None:
print (cell_phone_info[key])
return
phoneNum = input("Please input the cell phone number:")
rs = re.match(r"1[3578]\d{9}$", phoneNum);
if rs != None:
OutputPhoneProvider(phoneNum)
else:
print("others")
3、 使用正則表達式判斷輸入奶茶編號,如果不在 1-5 範圍內,輸出: Woops!我們只售賣以上五種奶茶哦!新口味敬請期待!
import re
teaNum = input("Please input the tea number:")
rs = re.match(r"[1-5]$", teaNum)
if rs.group() == None:
print("Woops! Please re-input the tea number!")