微信公眾號:CodeId
有什么建議可以到公眾號里進行留言。
本篇文章主要介紹python
有關正則表達式的使用。說到使用正則表達式,我們首先應該了解什么是正則表達式,簡單的說,正則表達式是一個描述字符串規則的代碼
。比如說我們經常使用的郵箱:1234567@qq.com
,1234567@163.com
…你會發現他們都有一定的規則,而這個規則的描述就涉及到具體的正則表達式語法了,下面我們就來了解一些基礎的語法:
1. 最簡單的正則表達式
最簡單的正則表達式其實就是普通字符串,它可以匹配其自身。
比如:正則表達式 'CodeId'
可以匹配字符串 CodeId
。
import re
result = re.search('CodeId','CodeId is very good')
print(result.group()) # CodeId
上述代碼是通過python
的re
(正則表達式)模塊對正則表達式的一個使用,其中re.search()
方法的作用就是對整個字符串進行搜索,并返回第一個匹配的字符串的匹配對象,匹配失敗會返回 None
,它的語法是:
re.search(pattern, string, flags=0)
-
pattern
:表示使用的正則表達式 -
string
:表示要匹配的字符串 -
flags
:用來控制正則表達式匹配規則的標志位
group()
方法的作用是:返回匹配的一個或多個子字符串
2. 限制數量的表達式(限定符)
在講解限定符之前,先講解一下什么是貪婪模式
和非貪婪模式
貪婪模式:是盡可能多的匹配。限定符默認都是貪婪模式的。
非貪婪模式:是盡可能少的匹配。
比如我有一個書柜可以放1到100本書,貪婪模式就是放盡可能的接近或等于100本書,而非貪婪模式就是放盡可能的接近或等于1本書。
一、*
:
作用:匹配前面的子表達式零次
或者多次
。
比如:ab*
它會匹配a
,ab
,abb
或者a
后面任意數量的b
import re
result1 = re.search('ab*','a')
print(result1.group()) # a
result2 = re.search('ab*','abbb')
print(result2.group()) # abbb
二、+
:
作用:匹配前面的子表達式一次
或者多次
比如:ab+
它會匹配ab
,abb
,abb
或者ab
后面任意數量的b
注意:*
和+
的區別就是:+
中的a
后面至少有一個b
,而*
中的a
后面可以沒有b
。
result1 = re.search('ab+','a')
print(result1) # None
result2 = re.search('ab+','abbb')
print(result2.group()) # abbb
三、?
:
作用1:匹配前面的子表達式零次
或者一次
比如:ab?
可以匹配a
或者ab
result1 = re.search('ab?','a')
print(result1.group()) # a
result2 = re.search('ab?','abbb')
print(result2.group()) # ab
作用2:指定限定符為非貪婪模式。
比如:ab*?
匹配字符串abbb
會返回a
result1 = re.search('ab*','abbb')# 貪婪模式
print(result1.group()) # abbb
result2 = re.search('ab*?','abbb')# 非貪婪模式
print(result2.group()) # a
result3 = re.search('ab+','abbb')# 貪婪模式
print(result3.group()) # abbb
result4 = re.search('ab+?','abbb')# 非貪婪模式
print(result4.group()) # ab
四、{n}
:
作用:對前面的子表達式重復n
次,n
是一個非負整數。
比如:Co{2}deId
可以匹配CoodeId
,但是不可以匹配CodeId
result = re.search('Co{2}deId','CoodeId')
print(result.group())# CoodeId
result = re.search('Co{2}deId','CodeId')
print(result) # None
五、{n,m}
:
作用:對前面的子表達式重復n
到m
次,n,m
是一個非負整數并且n<=m
。其中n
和m
是可以省略其中一個。比如:
-
{n,}
:表示對前面的子表達式至少重復n
次。 -
{,m}
:表示對前面的子表達式至多重復m
次。
result = re.search('Co{2,}deId','CooodeId')
print(result.group())# CooodeId
result = re.search('Co{,2}deId','CodeId')
print(result.group()) # CodeId
result = re.search('Co{2,4}deId','CooodeId')
print(result.group()) # CooodeId
3.定位符號
定位符用來描述字符串或單詞的邊界。指定在字符串的什么位置開始匹配。
定位符號如下:
一、^
:
作用1:匹配字符串開始的位置。如果是多行模式,還會與\n
,\r
之后
的位置匹配。
比如:^CodeId
會匹配CodeId
,CodeIda
,不會匹配aCodeId
result = re.search('^CodeId','CodeIda')
print(result.group()) # CodeId
result = re.search('^CodeId','aCodeIda')
print(result) # None
result = re.search('^CodeId','a\nCodeIda',re.MULTILINE) # 多行模式下
print(result.group()) # CodeId
re.MULTILINE
是設置為多行模式
作用2:^
在方括號表達式中使用,表示不
的意思。
比如:[^1]
表示匹配不是字符1
。
result = re.search('[1]','a1')
print(result.group()) # 1
result = re.search('[^1]','a1')
print(result.group()) # a
二、$
:
作用:匹配字符串結尾的位置。如果是多行模式,還會與\n
,\r
之前
的位置匹配。
比如:ab$
會匹配cdab
,asab
。
result = re.search('ab$','cdab')
print(result.group()) # ab
result = re.search('ab$','abcd')
print(result) # None
三、\b
:
作用:匹配單詞的開始或結束的位置.
比如:ry\b
就是匹配單詞中以ry
結尾匹配項。\bis
是匹配單詞中以is
開始的匹配項
result = re.search(r'ry\b','CodeId is very good')
print(result.group()) # ry
result = re.search(r'\bis','CodeId is very good')
print(result.group()) # is
result = re.search(r'\babc\b','bc abc abc')
print(result.group()) # abc
四、\B
:
作用:不是匹配單詞開始或結束的位置,和\b
是相反的。
比如:\Ba
它表示匹配不以a
開始的單詞,所以可以匹配bac
,cba
但是不能匹配abc
result = re.search(r'\Ba','bac')
print(result.group()) # a
result = re.search(r'\Ba','abc')
print(result) # None
4.一般字符
一、.
:
作用:匹配除換行符之外的任何單個字符。
比如:ab.
可以匹配abc
,abd
,abe
等等
result = re.search(r'Co.e.d','CodeId')
print(result.group()) # CodeId
二、\
:
作用:轉義字符,改變后面一個字符原本的字符意思。
比如:n
原本匹配字符n
,但是在前面加上\
之后就變成\n
,用來匹配換行符。
result = re.search(r'Co\n.','Co\ndeId')
print(result.group())
'''
Co
d
'''
三、[]
:
作用:字符集合。匹配集合中所包含的任意一個字符。其中集合中的元素可以一一列出,也可以寫范圍。
比如:[abco]
可以匹配CodeId
中的o
。[0-9]
等同于[0123456789]
。
result = re.search(r'[0-9]','a1b')
print(result.group()) # 1
result = re.search(r'[oI]','CodeId')
print(result.group()) # o
注意:如果[]
里面的第一個字符是^
,那么表示取反的意思。比如:[^0-9]
表示匹配不是數字的字符。
result = re.search(r'[^0-9]','a1b')
print(result.group()) # a
四、|
:
作用:或的意思
比如:x|y
表示先匹配x
表達式如果不成功就匹配y
表達式。
result = re.search(r'ab|ac','abc')
print(result.group()) # ab
5.分組
分組不是對數據進行分組,而是對匹配的表達式進行分組。看一下下面的講解應該會明白一些。
一、(...)
:
作用:可以匹配括號中的任何表達式,同時也標志著組的開始和結束。當表達式中有多個括號時,從左向右,第一個左括號為第一組,第二個左括號為第二組,以此類推。
比如:(a){2}(b){3}
會匹配aabbb
,其中a
是第一組,b
是第二組
result = re.search(r'(a){2}(b){3}(c*)','aabbb')
print(result.group()) # aabbb
print(result.groups()) # ('a', 'b', '')
注意:result.groups()
的作用是返回所有匹配的子組的元組,比如上面a
,b
都匹配上了,而c
沒有匹配上所以返回c
組為空
二、(?P<name>...)
:
作用:在分組的同時,為組起一個名稱,這個組名稱必須是有效的Python標識符,并且每個組名稱只能在正則表達式中定義一次。
比如:(?P<A>a)
就是為組起了一個名稱A
.
result = re.search(r'(?P<A>a){2}(b){3}(a*)','aabbb')
# 通過組名稱來組的匹配內容
print(result.group('A')) # a
三、(?P=name)
:
作用:引用表達式前面組中名稱為name
的組的匹配內容。
比如:(?P<A>.){2}(b){3}(?P=A)
匹配的字符可以是aabbba
,ccbbbc
,ddbbbd
….
result = re.search(r'(?P<A>.){2}(b){3}(?P=A)','aabbba')
print(result.group()) # aabbba
四、\number
:
作用:引用表達式中編號為number
的組的匹配內容。
比如:([0-9])([a-z])\1
匹配的字符串有1a1
,2s2
,6a6
…
result = re.search(r'([0-9])([a-z])\1','6a6')
print(result.group())# 6a6
6.反向引用
反向引用涉及到組(被圓括號括起來的部分),組在匹配到內容時,會存儲到緩沖區,按照存儲的先后順序,分別編號為1,2,3…99,最高到99
。每個緩沖區的內容可以使用\number
的方式進行訪問調用。
7.非獲取匹配
非獲取匹配:就是組中匹配的內容不進行緩存,不供以后使用
一、(?:...)
:
作用:可以匹配括號中的任何表達式,但是不進行緩存以供后面使用。
比如:(?:123)abc\1
表達式會報錯,因為前面的組沒有進行緩存,\1
調用時會失敗。
二、(?=...)
:
作用:起到一個條件約束的功能,約束括號前面的字符串。看做如果是...
比如:ab(?=c)
會匹配abc
中的ab
但是不會匹配abd
中的ab
。換一種說法就是:如果ab
的后面是c
就匹配成功,否則失敗。
result = re.search(r'ab(?=c)','abc')
print(result.group()) # ab
result = re.search(r'ab(?=c)','abd')
print(result) # None
三、(?!...)
:
作用:起到一個條件約束的功能,約束括號前面的字符串。看做如果不是...
比如:ab(?!c)
會匹配abd
中的ab
但是不會匹配abc
中的ab
。換一種說法就是:如果ab
的后面不是c
就匹配成功,否則失敗。
result = re.search(r'ab(?!c)','abc')
print(result) # None
result = re.search(r'ab(?!c)','abd')
print(result.group()) # ab
四、(?<=...)
:
作用:起到一個條件約束的功能,約束括號后面的字符串。看做如果前面是...
比如:(?<=c)ab
會匹配cab
中的ab
,但是不會匹配dab
中的ab。換一種說法就是:如果ab
的前面是c
就匹配成功,否則失敗。
result = re.search(r'(?<=c)ab','cab')
print(result.group()) # ab
result = re.search(r'(?<=c)ab','dab')
print(result) # None
五、(?<!...)
:
作用:起到一個條件約束的功能,約束括號后面的字符串。看做如果前面不是...
比如:(?<!c)ab
會匹配dab
中的ab
但是不會匹配cab
中的ab
。換一種說法就是:如果ab
的前面不是c
就匹配成功,否則失敗。
result = re.search(r'(?<!c)ab','cab')
print(result) # None
result = re.search(r'(?<!c)ab','dab')
print(result.group()) # ab
8.表達式的注釋
注釋在表達式中起到解釋說明的作用。
一、(?#...)
:
作用:起到注釋作用,括號中的字符在表達式中運行時,不啟動用。
比如:a(?#letter)
只會匹配單個字符a
,而letter
是解釋說明a
是一個字母,方便閱讀。
result = re.search(r'a(?#letter)','cab')
print(result.group()) # a
9.預定義
就是提前設定好一些字符代表什么意思,用來替換一些復雜的字符。
一、\d
和\D
:
代表:一個表示[0-9]
,另一個表示[^0-9]
,它倆是對立的。
作用:\d
表示匹配0-9
中任意一個數字。\D
表示匹配非數字的字符。
比如:a\d
可以匹配a1
,a0
,a2
,a6
…;而a\D
表示匹配aa
,ab
,a;
只要a
后面不是數字就行。
result = re.search(r'a\d','a1')
print(result.group()) # a1
result = re.search(r'a\D','a1')
print(result) # None
二、\w
和\W
:
代表:一個表示'[A-Za-z0-9_]
,另一個表示'[^A-Za-z0-9_]
,它倆是對立的。
作用:\w
表示匹配字母、數字、下劃線;\W
表示匹配非字母數字下劃線。
比如:\w+
匹配13,
時會得到13
,而\W+
匹配時只會匹配到,
result = re.search(r'\w+','13,')
print(result.group()) # 13
result = re.search(r'\W+','13,')
print(result.group()) # ,
三、\s
和\S
:
代表:一個表示[ \f\n\r\t\v]
,另一個表示[^ \f\n\r\t\v]
;
作用:\s
表示匹配任何空白字符,包括空格、制表符、換頁符等等,而\S
表示匹配任何非空白字符。
比如:a\sc
可以匹配a c
,而a\Sc
卻不能。
result = re.search(r'a\sc','a c')
print(result.group()) # a c
result = re.search(r'a\Sc','a c')
print(result) # None
四、\A
和\Z
:
作用:\A
表示匹配字符串的開頭,\Z
表示匹配字符串的結尾。
比如:\Aa
會匹配字符串abcdcba
中,開始的a
,a\Z
會匹配字符串abcdcba
中結尾處的a
。
result = re.search(r'\Aa','abcdcba')
print(result) # <_sre.SRE_Match object; span=(0, 1), match='a'>
result = re.search(r'a\Z','abcdcba')
print(result) # <_sre.SRE_Match object; span=(6, 7), match='a'>
今天的學習暫時告一段落,后面會不定時更新的。送大家一句話人必須相信自己,這是成功的秘訣
下面是我的公眾號:CodeId 歡迎關注