1.什么是正則表達(dá)式
正則表達(dá)式就是字符匹配的工具纯丸,是由正則符號和普通字符組成,來匹配不同規(guī)律的字符串。
2.python對正則表達(dá)式的支持耍目。
python中提供了一個re模塊 用來支持正則表達(dá)式
fullmuch(正則表達(dá)式,字符串) - 用正則表達(dá)式去完全匹配徐绑,如果匹配成功邪驮,返回一個匹配結(jié)果,失敗返回None
python中的正則表達(dá)式的寫法:將正則內(nèi)容寫在字符串中傲茄,一般這個字符串前面會加r\R
1.普通字符
普通字符在正則表達(dá)式中毅访,代表字符本身。
#匹配字符串盘榨,第一個字符a喻粹,第二個字符b,第三個字符也是最后一個字符“c”
re_str = r"abc"
result = re.fullmatch(re_str,"abc")
print(result)
3 . (匹配任意字符)
在正則表達(dá)式中 . 出現(xiàn)的位置草巡,可以匹配一個任意字符
注意:一個.只能匹配一個字符
re_str = r"a.c"
result = re.fullmatch(re_str,"ahc")
print("....",result)
4 \w(匹配字母數(shù)字或者下劃線)
在這正則表達(dá)式中查乒,\w出現(xiàn)的位置弥喉,可以匹配一個任意的字母,數(shù)字或者下劃線
一個\w只能匹配一個字符玛迄,\w出現(xiàn)的文字由境,可以匹配任意的字母,數(shù)字下劃線
(其實亦可以匹配Unicode編碼中蓖议,除了ASCII碼剩下的部分)中文也可匹配
#匹配一個長度是6的下劃線,前三位字母數(shù)字中文等虏杰,后面是任意字符i字符
re_str = r"\w\w\w..."
result = re.fullmatch(re_str,"_5禹dsa")
print("\w",result)
5 \s匹配空白字符
空白字符包括:空格,制表符拒担,和換行符嘹屯,(\t,\n,\r)
#匹配一個長度是4的字符串,并且字符串前兩位是字母數(shù)字或者下劃線(中文)从撼,中間一個空白州弟,最后是數(shù)字字母下劃線
re_str = r"\w\w\s\w"
result = re.fullmatch(re_str,"da\t8")
print("\s",result)
print(len("da\t8"))
6 \d(匹配數(shù)字字符)
#匹配一個長度是5的字符串,字符串的前三位是數(shù)字字符低零,后面兩個是任意字符
re_str = r"\d\d\d.."
result = re.fullmatch(re_str,"536da")
print("\d",result)
7 \b(檢測單詞邊界)
注意:\b是檢測\b出現(xiàn)的位置是否是單詞邊界婆翔,不會對字符進(jìn)行匹配。
當(dāng)正則表達(dá)式中出現(xiàn)了\b掏婶,匹配的時候去掉\b啃奴,匹配成功后再看\b出現(xiàn)的位置是否是單詞邊界。
單詞邊界:字符串開頭雄妥,字符串結(jié)尾最蕾,單詞開頭,單詞結(jié)尾老厌,標(biāo)點(diǎn)符號瘟则,空白符號(只要可以將兩個單詞區(qū)分開的符號都屬于單詞邊界。)
#匹配字符串“hello枝秤,word并且要求w前面是單詞邊界”
re_str = r"hello,\bword"
result = re.fullmatch(re_str,"hello,word")
print(result)
8^ 檢測字符串開頭
match和fullmatch中沒有意義醋拧,serach和findall中有意義.
#匹配一個字符串前面三個是The,后面兩個任意字符
re_str = r"^The.."
result = re.fullmatch(re_str,"The2a")
print(result)
re_str = "The.."
print("search:",re.search(re_str,"xxxThe2:"))
9 $(檢測字符串中結(jié)尾)
match和fullmatch中沒有意義淀弹,serach和findall中有意義.
re_str =r"..\dThe$"
result = re.fullmatch(re_str,"aa5The")
print("$",result)
re_str =r"..\dThe" #沒有$
print("search:",re.search(re_str,"aa5Thesad"))
\大寫字母 對應(yīng)的功能格式 \小寫字母 功能區(qū)分
\W - 匹配非數(shù)字字母下劃線
\D - 匹配非數(shù)字字符
\S - 檢測非空白字符
\B - 檢測非單詞邊界
re_str = r"\d\D\s\s\Ba"
result = re.fullmatch(re_str,"94\t\ta")
print("前面有一個\s是單詞邊界:",result) #前面有一個\s是單詞邊界: None
re_str = r"\d\D\s\w\Ba"
result = re.fullmatch(re_str,"9h\t_a")
print("\B前面有一個不是單詞邊界:",result)
--- | --- |
---|---|
[字符1 - 字符2] | 表示字符1到字符2(注意:要求字符1的編碼值要小于字符2的編碼值丹壕。) |
[a-z] | 表示匹配所有小寫字母 |
[A-Z]] | 匹配所有的大寫字母 |
[a-zA-Z] | 匹配所有字母 |
[\u4e00 - \u9fa5] | |
[字符1字符2-] | 這兒的減號就表示減號本身 |
re_str = r"[1-7]100[a-z]"
result = re.fullmatch(re_str,"5100g")
print("[字符1 - 字符2]11",result)
#匹配1-7的數(shù)字字符,第二個是abc-中的一個薇溃,第三個是小寫字母
re_str = r"[1-7][abc-][a-z]"
result = re.fullmatch(re_str,"5-z")
print("[字符1 - 字符2]22",result)
11[^字符集] - 匹配不在字符集中的任意字符
--- | --- |
---|---|
[^abc]不是abc | |
[^\d] | 除了數(shù)字字符的任意字符 |
[^a-z] | 匹配除小寫的其他任意字符 |
[abc^] | 這里的^ 表示 ^菌赖。 |
.#三個字符,第一個不是1-7沐序,第二個不是abc-琉用,第三個不是a-z
re_str = r"[^1-7][^abc-][^a-z]"
result = re.fullmatch(re_str,"0H羅")
print("^[字符1 - 字符2]22",result)
2忿峻。正則控制匹配次數(shù)
1.匹配0次或多次
--- | --- |
---|---|
a*]a出現(xiàn)0次或者多次 "","a","aa" | |
\d* | 任意數(shù)字出現(xiàn)多次或者零次 |
[abc]* | abc出現(xiàn)0次或者多次 |
[A-F]* | A到F中任意字符出現(xiàn)多次或者0次 |
注意哦:在[ ]外面的前面需要一個字符或者一個匹配字符的符號,不能單獨(dú)用*
print(re.fullmatch(r"a*",""),re.fullmatch(r"a*",""))
print(re.fullmatch(r"a*b","aaab"),re.fullmatch(r"a*b","aaab"))
print("\d*",re.fullmatch(r"\d*","12563"))
print("[abc]*",re.fullmatch(r"[abc]*","abc"),re.fullmatch(r"[abc]*","aaa"))
2.# +(匹配一次或者多次)
a+ - a至少出現(xiàn)1次
\d+ -數(shù)字字少出現(xiàn)一次
print("a+",re.fullmatch(r"a+b","ab"),re.fullmatch(r"a+b","aaab"))
3 ? (出現(xiàn)0次或者1次)
a? - a出現(xiàn)0次或者1次辕羽,“”逛尚,“a”可以匹配
# 寫出一個正則表達(dá)式(整數(shù)和負(fù)數(shù)都可以匹配)例如:123,-120
re_str = r"[-+]?[1-9]\d*"
result = re.fullmatch(re_str,"+30")
print("整數(shù)和負(fù)數(shù)都可以匹配",result)
4.{ }的用法
{N} - 匹配N次刁愿,a{3}:匹配3個“a”
{M绰寞,N} - 匹配M到N次,匹配三個a铣口,四個a滤钱,或者5個a
{,N}- 最多匹配N次(0-N) 例如:a{脑题,3}“”件缸,“a”,“aa”"aaa"
{M叔遂,} - 至少匹配M次
#練習(xí):輸入密碼他炊。密碼要求,字母和數(shù)字組成已艰,數(shù)字不開頭痊末,6-12位,給出提示是否正確
pw = input("輸入密碼:")
re_str = r"[a-zA-Z][\da-zA-Z]{5,11}"
result = re.fullmatch(re_str,pw)
print(result)
if result:
print("輸入成功哩掺!")
else:
print("輸入有誤凿叠!")
3捕獲與貪婪
1 分之.
條件1 | 條件2 :匹配條件1或者條件2.
\d | [a-z] - [\da-z]
\d{2} | [a-z] :匹配兩個數(shù)字或者1個a-z
a\d{2}|\w{2}
** 注意:正則中的分之也會出現(xiàn)短路,當(dāng)條件1可以匹配嚼吞,就不會再用第二個匹配**
print("分之",re.fullmatch(r"\d{2}|[a-z]","z"))
print("分之",re.fullmatch(r"a\d{2}|\w{2}","__"))
# 習(xí):寫一個正則表達(dá)式盒件,匹配所有的數(shù)。正的舱禽,負(fù)數(shù)炒刁,0
re_str = r'[-+]?[1-9]\d*[.]?\d*|[+-]?0[.]\d+|0'
print(re.fullmatch(re_str, '-0.02'))
4 - 捕獲和分組
- a.分組 - 將括號中的內(nèi)容作為一個整體
# 匹配一個字符串,前三位是'abc',后三位是三個數(shù)字或者三個大寫字母
re_str1 = r'abc\d{3}|abc[A-Z]{3}'
re_str2 = r'abc(\d{3}|[A-Z]{3})'
print(re.fullmatch(re_str2, 'abc123'))
re_str = r'(\d[a-z]){3}'
print(re.fullmatch(re_str, '2s3f4h'))
- b.捕獲
通過正則表達(dá)式獲取符合條件的子串的時候呢蔫,可以在正則表達(dá)式中加括號切心,匹配后只獲取括號里面出現(xiàn)的內(nèi)容
re.findall(正則表達(dá)式飒筑,字符串) - 在字符串中去獲取符合正則表達(dá)式條件的所有子串片吊,返回的是列表
str1 = "dasdad454a13ada2x1ad56a44g4fdad"
# 捕獲括號中的內(nèi)容
print(re.findall(r"a\d+",str1))
print(re.findall(r"a(\d+)",str1))
- c.重復(fù)匹配
帶多個分組的正則表達(dá)式中可以分組的后面通過添加\數(shù)字來重復(fù)前面第幾個分組中匹配到的內(nèi)容.
說明:\數(shù)字 - 這兒的數(shù)字代表前面第幾個分組\1代表第一個分組,\2代表一個分組
re_str = r"\d{3}([a-z]{2})a\1"
print("第一分組重復(fù)",re.fullmatch(re_str,"234heahe"))
re_str = r"(\d{3})([a-z]{2})a\1{2}\2"
print("第一分組重復(fù)2协屡,第一分組重復(fù)1",re.fullmatch(re_str,"123bba123123bb"))
re_str = r"(\d{3})L\1{2}([a-z]{2})a\2"
print("分組重復(fù)可以放前面去",re.fullmatch(re_str,"123L123123bbabb"))
3.貪婪
匹配次數(shù)后面加俏脊?就是貪婪匹配“*?肤晓,+爷贫?认然,??.{M,N}?,{M,}漫萄?
re_str = "a.+b"
str1 = "xxxahdjblkaluiihjlb"
print("非貪婪",re.findall(re_str,str1))
re_str = "a.+?b"
str1 = "xxxadfgjblkaluibihjalb"
print("貪婪",re.findall(re_str,str1))
4 轉(zhuǎn)義字符
在正則表達(dá)式中可以有特殊意義或者特殊功能的符號前加\來取消其特殊功能
在正則表達(dá)式中可以在有特殊意義或者特殊功能的符號前加\來取消其特殊功能
\\w - 代表兩個字符卷员,分別是'\'和w
\+ - 代表+字符
\* - 代表*字符
\? - 代表?字符
[], (), {}表示字符的時候,前面也要加\
注意:在中括號中, \必須加\表示\本身腾务,^在最前面加\表示^本身毕骡, -在兩個字符之間加\表示-本身
re_str = r'\\w-\d{3}'
print(re.fullmatch(re_str, '\w-232'))
re_str = r'a\+\(\d{2}\)'
print(re.fullmatch(re_str, 'a+(23)'))
re_str = r'[\^a1\-9]'
print(re.fullmatch(re_str, '3'))
3.re模塊
1.compile(了解)
compile(正則表達(dá)式) - 將正則表達(dá)式轉(zhuǎn)換成正則表達(dá)式對象
轉(zhuǎn)換成對象后可以通過對象調(diào)用對象方法
re_str = '\d{3}'
re_obj = re.compile(re_str)
# 調(diào)用模塊中的函數(shù)
print(re.fullmatch(re_str, '234'))
# 調(diào)用對象方法
print(re_obj.fullmatch('234'))
2.match和fullmatch
- a. fullmatch(正則表達(dá)式, 字符串) - 完全匹配,從字符串開頭匹配到字符串結(jié)束
- b. match(正則表達(dá)式, 字符串) - 不完全匹配岩瘦,只匹配字符串開頭
匹配成功返回匹配對象未巫,匹配失敗返回None
re_str = r"\d[A-Z]{2}"
result = re.match(re_str,"8HHdjadnksan")
print("只是匹配字符串開頭:",result)
匹配對象特別篇
- 1.span -匹配到內(nèi)容的范圍(開始下標(biāo),結(jié)束下標(biāo))
匹配對象.span()獲取整個正則表達(dá)式匹配到的范圍
匹配對象.span(n)獲取正則表達(dá)式中第n個分組匹配到的范圍(前提是有分組)
re_str = r"\d([A-Z]{2})"
result = re.match(re_str,"8HHdjadnksan")
print("整個范圍",result.span())
print("匹配對象的范圍",result.span(1))
- 2.start和end - 獲取匹配結(jié)果的開始下標(biāo)和結(jié)束下標(biāo)
匹配對象.start()/匹配對象.end()- 獲取整個正則表達(dá)式匹配到的開始下標(biāo)/結(jié)束下標(biāo)
匹配對象.start(n)獲取正則表達(dá)式中第n個分組匹配到的開始/結(jié)束下標(biāo)
re_str = r"\d[A-Z]{2}"
result = re.match(re_str,"8HHdjadnksan")
print("開始下標(biāo)",result.start())
print("結(jié)束下標(biāo)",result.end())
re_str = r"\d([A-Z]{2})"
result = re.match(re_str,"8HHdjadnksan")
print("分組開始下標(biāo)",result.start(1))
print("分組結(jié)束下標(biāo)",result.end(1))
- 3.group - 獲取匹配到的內(nèi)容
匹配對象.group() - 獲取正則表達(dá)式匹配帶的內(nèi)容
匹配對象.group(n) - 獲取正則表達(dá)式第n個分組的內(nèi)容
re_str = r"\d([A-Z]{2})"
result = re.match(re_str,"8HHdjadnksan")
print("整個表達(dá)式結(jié)果",result.group())
re_str = r"\d([A-Z]{2})"
result = re.match(re_str,"8HHdjadnksan")
print("第一組的結(jié)果",result.group(1))
- 4.string - 獲取用來匹配的原字符串
匹配對象.string
re_str = r"\d[A-Z]{2}"
result = re.match(re_str,"8HHdjadnksan")
print("整個表達(dá)式結(jié)果",result.string)
3.search
search(正則表達(dá)式启昧,字符串) - 匹配字符串中第一個滿足正則表達(dá)式的子串叙凡,如果匹配成功,
返回匹配對新疆愛那個密末,否則返回None
str1 = "abc123dsfkjkjaskdjd"
result = re.search(r"\d{3}[a-z]{2}",str1)
print(result)
4.split(正則表達(dá)式握爷,字符串)
split(正則表達(dá)式,字符串) - 在字符串中严里,按照滿足正則表達(dá)式條件的子串對字符進(jìn)行切割
str1 = "ads5had5f-ha9rda6adg"
result = re.split(r"\d+",str1)
print("split切割:",result)
result = re.split(r"\d+|[+*-]+",str1)
print("split切割:",result)
5 sub(正則表達(dá)式饼拍,新子串,字符串)
sub(正則表達(dá)式田炭,新子串师抄,字符串)用新的字符串替換字符串中滿足正則表達(dá)式的子串,返回一個替換后的子串
str1 = "你是傻 叉教硫,操你大爺?shù)倪端保現(xiàn)uck you"
result = re.sub(r"[丫艸操]|[Fuck]|傻\s*叉","*",str1)
print("sub替換:",result)
6.findall(正則表達(dá)式,字符串) - 在字符串中獲取滿足正則表達(dá)式的所有字符串瞬矩,返回一個列表
列表元素是字符串
注意:
正則表達(dá)式中有一個分組茶鉴,結(jié)果是列表中只取分組匹配到的結(jié)果。
如果正則表達(dá)式分組的個數(shù)大于1景用,結(jié)果是一個列表涵叮,列表中的元素是元組
str1 = "dafdd5as45d4ad4as4d54sg545f4j5h4j54ds=="
result = re.findall(r"[a-zA-Z]{2,}\d+[a-z]+",str1)
print("不加貪婪",result)
str1 = "dafdd5as45dds4ad4as4dda54dasg545f4j5h4j54ds=="
result = re.findall(r"[a-zA-Z]{2,}(\d+)([a-z]+?)",str1)
print("加貪婪",result)
str1 = "dafdd5as45d4ad4as4d54sg545f4j5h4j54ds=="
result = re.findall(r"[a-zA-Z]{2,}(\d+)([a-z]+?)",str1)
print("加括號元組",result)
7.finditer(正則表達(dá)式,字符串)
獲取字符串中滿足正則表達(dá)式的內(nèi)容伞插,返回結(jié)果是一個迭代器
迭代器中的元素就是匹配對象
str1 = "dafdd5as45d4ad4as4d54sg545f4j5h4j54ds=="
result = re.finditer(r"[a-zA-Z]{2,}\d+[a-z]+",str1)
print("finditer迭代器",result)
print(next(result))
\
#思考 :寫一個自己的finderiter
def yt_finditer(patteran,string):
re1 = re.finditer(patteran,string)
while re1:
yield re1
string = string[re1.end():]
re1 = re.finditer(patteran, string)
str1 = "dafdd5as45d4ad4as4d54sg545f4j5h4j54ds=="
result = yt_finditer(r"[a-zA-Z]{2,}\d+[a-z]+",str1)
print("取結(jié)果",next(result))