python~正則表示式總結一
目錄
re.match(pattern, string, flags=0)方法
re.search(pattern, string, flags=0)方法
re.findall(pattern, string, flags=0)方法
re.finditer(pattern, string, flags=0)方法
re.split(pattern, string, maxsplit=0, flags=0)方法
re.sub(pattern, repl, string, count=0, flags=0)方法
re.subn(pattern, repl, string, count=0, flags=0)方法
正則表示式總結
正則表示式是一個特殊的字元序列,描述了一種字串匹配的模式,可以用來檢查一個串是否含有某種子串;可以做精確匹配,模糊匹配,進行字串替換、切割,尤其是在分析日誌時用的比較多。
python處理正則表示式的模組是re模組,它是python語言中擁有全部的正則表示式功能的模組;正則表示式由一些普通字元和一些元字元組成,普通字元包括大小寫的字母,數字和列印符號,而元字元是具有特殊含義的字元;
1.正則表示式模式
正則表示式大致的匹配過程是: 拿正則表示式依次和字串做比較,如果每一個字元都匹配,則匹配成功,只要有一個匹配不成功的字元,則匹配不成功。
需要注意的是:
由於正則表示式通常包含反斜槓等特殊字元,所以我們最好使用原始字串來表示他們。如:r’\d’,等價於’\\d’,表示匹配一個數字。
Python正則表示式中,數量詞預設都是貪婪的,它們會盡力盡可能多的去匹配 滿足的字元,但是如果我們在後面加上問號“?”,就可以遮蔽貪婪模式,表示匹配儘可能少的字元。
2.特殊表示式含義
符號 |
含義 |
舉例 |
一般字元(匹配自身) |
||
.(點) |
匹配除換行符之外的任意一個字元 |
a.c可以匹配abc |
\(反斜槓) |
轉義一個特殊的字元,使這個字元表示原來字面上的意思。如"\$",表示原字元$,而不是正則表示式中表示匹配行尾的意思。 |
a\.c匹配a.c |
預定義字符集(可以寫在[]中) |
||
[...](方括號) |
匹配括號中出現的任意單個字元 |
a[123]b匹配a1b、a2b、a3b |
[^...] |
不匹配方括號中列出的單個字元(注意只能針對單個字元) |
[^ab]匹配除a和b之外的字元 |
\d |
匹配任意一個數字,範圍[0-9] |
a\dc可以匹配a1c、a2c等 |
\D |
匹配任意一個非數字字元,等價於[^\d] |
1\D2可匹配1a2等 |
\s |
匹配任意一個空白字元,如[空格\t\r\n\v\f] |
a\sf可以匹配a f等 |
\S |
匹配任意一個非空白字元,等價於[^\s] |
a\Sg可以匹配agg等 |
\w |
匹配一個字母或數字,字元範圍[a-zA-Z0-9] |
1\w2可以匹配112、1a2等 |
\W |
匹配一個非字母或非數字,等價於[^\w] |
|
數量字符集(用在字元或分組符(...)之後,非貪婪匹配*? +? |
||
*(星號) |
匹配前一個字元0次1次或多次 |
abc*可以匹配ab,abc,abcc等 |
+(加號) |
匹配前一個字元1次或多次 |
abc+可以匹配abc,abcc等 |
?(問號) |
匹配前一個字元0次或多次 |
abc?可以匹配ab,abc |
{m} |
匹配前一個字元m次 |
qc{3}匹配結果qccc |
{m,n} |
匹配前一個字元m到n次; |
1{2,5}c匹配結果11c,111c,1111c,11111c |
邊界匹配符 |
||
^(託字元) |
匹配字串開頭,如果是多行則匹配每一行的開頭。在[...]中,^表示否定,如非數字[^0-9] |
^123匹配123 |
$(美元符) |
匹配字串或一行的結尾,如果是多行則匹配每一行的結尾 |
abc$匹配abc |
\A |
僅匹配字串的開始 |
\A12AC匹配12AC |
\b |
匹配一個單詞的邊界,也就是單詞和空格間的位置。如"st",可以匹配"a test of"中的"st",但不匹配"tester"中的"st" |
re.search(r"st\b","a test of")有匹配結果 |
\B |
[^\b],表示匹配非單詞邊界 |
re.search(r"st[^\b]","a test of ")匹配'st ' |
\Z |
匹配字串結束,如果存在換行,只匹配到換行前的結束符 |
re.search(r"\w+\Z","ABC")匹配"ABC" |
邏輯匹配符 |
||
|(或) |
表達左右正則表示式任意匹配一個,如果左邊的表示式匹配上了,匹配結束,不再匹配右邊的表示式; |
re.search(r"12|43","1243")匹配"12" |
分組匹配 |
||
(...) |
後向引用。用()括起來的正則表示式將被作為一個分組,從正則表示式的左邊依次算起,有多少個左括號"(",就有多少個分組,分組的編碼從1依次加1,無論括號中是否巢狀括號。並且分組表示式作為一個整體,後可接數量詞。 |
(xyz){2}滿足xyzxyz |
\(number) |
引用分組匹配到的分組編號為<number>的字串 |
如:\1...\9 |
(?P<name>...) |
命名分組,除了預設的分組編號外再指定一個別名分組,注意:P是大寫 |
re.search(r"(?P<數字>\d+)","sad23").group("數字") |
(?P=name) |
引用別名為name的分組匹配,這個是在正則表示式中引用,表示匹配重複的字串,也可以是使用編號引用。注意:P是大寫,引用分組時內容需一致 |
|
特殊匹配符(不能作為分組使用) |
||
(?<!pattern) |
前向否定,表示在前面(?!pattern)匹配的內容不存在,它後面的正則才生效,返回後面正則匹配的內容 |
re.search(r"(?<!abc)\d+","abc12")匹配結果為"2" |
(?!pattern) |
後向否定,表示在後面(?!pattern)匹配的內容不存在,它前面的正則才生效,返回前面正則匹配的內容 |
re.search(r"\d+(?!\w+)","23ds 4323")匹配結果為"4323" |
(?<=pattern) |
前向肯定,表示在前面(?<=pattern)匹配的內容存在,它後面的正則才生效,返回後面正則匹配的內容 |
re.search(r"(?<=[abc])\d+","abc123").group()匹配結果為"123" |
(?=pattern) |
後向肯定,表示在後面(?=pattern)匹配的內容存在,它前面的正則才生效,返回前面正則匹配的內容 |
re.search(r"\d+(?=abc)","abc123abc").group()匹配結果為"123" |
2.1 .(點)
匹配除換行符之外的任意一個字元,在DOTALL模式中是可以匹配換行符
>>> import re
>>> re.match(r".","abc")
<_sre.SRE_Match object; span=(0, 1), match='a'> #匹配結果物件
>>> re.match(r"..","abc")
<_sre.SRE_Match object; span=(0, 2), match='ab'>
span :匹配結果的起始位置和結束位置,開區間
>>> re.match(r"....","abc")
>>> print (re.match(r"....","abc"))
None
>>> print (re.match(r"..","a\nc"))
None
>>> print (re.match(r"..","a\nc",re.DOTALL))
<_sre.SRE_Match object; span=(0, 2), match='a\n'>
2.2 \(斜槓)
轉義符,轉義一個特殊的字元
>>> print (re.match(r"\..",".a\nc",re.DOTALL))
<_sre.SRE_Match object; span=(0, 2), match='.a'>
>>> print(re.match(r"\\","\\a\nc"))
<_sre.SRE_Match object; span=(0, 1), match='\\'>
2.3 [...](方括號)
匹配括號中出現的任意單個字元;
>>> print (re.match(r"[abc]","ac"))
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> print (re.match(r"[abc]","bc"))
<_sre.SRE_Match object; span=(0, 1), match='b'>
>>> print (re.match(r"[abc]","cc"))
<_sre.SRE_Match object; span=(0, 1), match='c'>
2.4 [^...]
在方括號中表示非的意思;不匹配方括號中列出的單個字元
>>> print (re.match(r"[^abc]","cc"))
None
>>> print (re.match(r"[^abc]","hc"))
<_sre.SRE_Match object; span=(0, 1), match='h'>
2.5 ^
不在方括號中,表示匹配字串開頭
>>> print(re.search(r"abc","sssssabc"))
<_sre.SRE_Match object; span=(5, 8), match='abc'>
>>> print(re.search(r"^abc","sssssabc"))
None
>>> re.search(r"^abc","dddabc") #沒有匹配結果
>>> re.search(r"^abc","abcdddabc")
<_sre.SRE_Match object; span=(0, 3), match='abc'>
>>> re.search(r"^\d+","1234s3254f")
<_sre.SRE_Match object; span=(0, 4), match='1234'>
2.6 \d
匹配字串中的任意一個數字,範圍為[0-9]
>>> re.match(r"\d","12")
<_sre.SRE_Match object; span=(0, 1), match='1'>
2.7 \D
匹配任意一個非數字字元,等價於[^\d]
>>> re.match(r"\D+","a123").group()
'a'
>>> re.match(r"\D+","abc123").group()
'abc'
2.8 \s
匹配任意一個空白字元,如[空格\t\r\n\v\f]
>>> re.match(r"\s"," 2")
<_sre.SRE_Match object; span=(0, 1), match=' '>
>>> re.match(r"\s","\n2")
<_sre.SRE_Match object; span=(0, 1), match='\n'>
>>> re.match(r"\s"," 2")
<_sre.SRE_Match object; span=(0, 1), match='\t'>
2.9 \S
匹配任意一個非空白字元,等價於[^\s]
>>> re.findall(r"\S+","\nAS\tet 32")
['AS', 'et', '32']
>>> "".join(re.findall(r"\S+","\nAS\tet 32"))
'ASet32'
2.10 \w
匹配一個數字、字母和下劃線,字元範圍:[a-zA-Z0-9]
>>> re.match(r"\w","2we")
<_sre.SRE_Match object; span=(0, 1), match='2'>
>>> re.match(r"\w","we")
<_sre.SRE_Match object; span=(0, 1), match='w'>
>>> re.match(r"\w","_we")
<_sre.SRE_Match object; span=(0, 1), match='_'>
2.11 \W
非數字、字母和下劃線,等價於[^\w]
>>> re.match(r"\W","*12we")
<_sre.SRE_Match object; span=(0, 1), match='*'
>>> re.search(r"\W+","23#@")
<_sre.SRE_Match object; span=(2, 4), match='#@'>
2.12 *(星號)
匹配一個字元0次或多次,需要注意的是正則預設的貪婪性,會在滿足匹配的條件下繼續貪婪更多的匹配
>>> re.search(r"\d*","asd")
<_sre.SRE_Match object; span=(0, 0), match=''> #匹配0次,返回為空
>>> re.search(r"\d*","123")
<_sre.SRE_Match object; span=(0, 3), match='123'>
>>> re.search(r"\d*?","123")
<_sre.SRE_Match object; span=(0, 0), match=''> #用問號抑制貪婪性,*最小匹配0次
2.13 +(加號)
匹配一個字元1次或多次,注意正則的貪婪性
>>> re.match(r"\d+","123d")
<_sre.SRE_Match object; span=(0, 3), match='123'>
>>> re.match(r"\d+?","123d")
<_sre.SRE_Match object; span=(0, 1), match='1'> #用問號抑制貪婪性,+最小匹配1次
2.14 ?(問號)
匹配一個字元0次或1次,用在數量詞(*/+/{m}/{m,n})的後面,表示抑制貪婪性
>>> re.match(r"\d?","as23")
<_sre.SRE_Match object; span=(0, 0), match=''>
>>> re.match(r"\d?","23abc")
<_sre.SRE_Match object; span=(0, 1), match='2'>
2.15 {}(大括號)
{m}:匹配前一個字元m次
{m,n}:匹配前一個字元m到n次;匹配前一個字元最少m次,最多n次
>>> re.search(r"a{3}","aabb")
>>> re.search(r"a{3}","aaabb")
<_sre.SRE_Match object; span=(0, 3), match='aaa'>
>>> re.search(r"a{2,4}","aabb")
<_sre.SRE_Match object; span=(0, 2), match='aa'>
>>> re.search(r"a{2,4}","aaabb")
<_sre.SRE_Match object; span=(0, 3), match='aaa'>
>>> re.search(r"a{2,4}","aaaabb")
<_sre.SRE_Match object; span=(0, 4), match='aaaa'>
>>> re.search(r"a{2,4}","aaaaabb")
<_sre.SRE_Match object; span=(0, 4), match='aaaa'>
2.16 ^(脫字元)
匹配字串開頭,如果是多行則匹配每一行的開頭。在[...]中,^表示否定,如非字母[^a-zA-Z],非數字[^0-9]
>>> re.search(r"^abc","abc12")
<_sre.SRE_Match object; span=(0, 3), match='abc'>
>>> re.search(r"^abc","abc12\nabc")
<_sre.SRE_Match object; span=(0, 3), match='abc'>
2.17 $(美元符)
匹配字串或一行的結尾,如果是多行則匹配每一行的結尾
>>> re.search(r"\d+$","asdf234")
<_sre.SRE_Match object; span=(4, 7), match='234'>
>>> re.search(r"^123$","123") #精確匹配
<_sre.SRE_Match object; span=(0, 3), match='123'>
2.18 \A
非多行匹配的時候等價於^,多行匹配的是\A將整個字串看作一個整體匹配,而^能夠匹配每一行的開頭
>>> re.findall(r"\A\d","12\n34\n565\n")
['1']
>>> re.findall(r"\A\d","12\n34\n565\n",re.M)
['1']
>>> re.findall(r"\A\d+","12\n34\n565\n",re.M)
['12']
>>> re.findall(r"^\d+","12\n34\n565\n",re.M)
['12', '34', '565']
2.19 \Z
非多行匹配時等價於$,多行匹配的是\Z將整個字串看作一個整體匹配,而$能夠匹配每一行的結尾
>>> re.findall(r"\d+$","abc43")
['43']
>>> re.findall(r"\d+\Z","abc43")
['43']
>>> re.findall(r"\d+\Z","abc43\new22\n5")
['5']
>>> re.findall(r"\d+\Z","abc43\new22\n5",re.M)
['5']
>>> re.findall(r"\d+$","abc43\new22\n5",re.M)
['43', '22', '5']
>>> re.findall(r"\d+$","abc43\new22\n5")
['5']
3.正則表示式
re.match(pattern, string, flags=0)方法
用於從字串的開始處進行匹配,如果在起始位置匹配成功,則返回Match物件,否則返回None
引數說明:
pattern:匹配的正則表示式
string:被匹配的字串
flags:標誌位,用於控制正則表示式的匹配方式,如是否區分大小寫,是否匹配多行等
>>> import re
>>> re.match(r"a","abc")
<_sre.SRE_Match object; span=(0, 1), match='a'>
#返回匹配結果物件,span表示是匹配的開始位置和結束位置,開區間
>>> print (re.match(r"a","bc"))
None
re.search(pattern, string, flags=0)方法
用於在整個字串中搜索第一個匹配的值,如果匹配成功,則返回Match物件,否則返回None
引數說明:
pattern:匹配的正則表示式
string:被匹配的字串
flags:標誌位,用於控制正則表示式的匹配方式,如是否區分大小寫,是否匹配多行等
>>> re.search(r"ac","vcac")
<_sre.SRE_Match object; span=(2, 4), match='ac'>
>>> print (re.search(r"ab","vcac"))
None
re.findall(pattern, string, flags=0)方法
用於在整個字串中查詢字串中所有能匹配的字串,如果匹配成功,則將結果存於列表中,然後返回該列表;否則返回空列表。特殊的地方在於返回的列表中的內容,取決於正則表示式中圓括號的出現情況,也就是分組情況。
引數說明:
pattern:匹配的正則表示式
string:被匹配的字串
flags:標誌位,用於控制正則表示式的匹配方式。如是否區分大小寫、是否多行匹配等
1.正則表示式中沒有圓括號時,返回列表中的元素由所有成功匹配的子串組成;
>>> import re
>>> re.findall(r"\d+","12ab34cd56ef")
['12', '34', '56']
>>> re.findall(r"\d+","abcdef")
[]
>>> res = re.findall(r'\w*oo\w*', 'woo this foo is too')
>>> print(res)
['woo', 'foo', 'too']
2.當正則表示式中含有多個圓括號()時,返回列表中的元素由所有滿足匹配的內容組成,但
是每個元素都是由表示式中所有圓括號匹配的內容組成的元組。而且元組中元素個數與括 號對數相同,並且字串排放順序跟括號出現的順序一致(一般看左括號‘ (’就行),
字串內容與每個括號內的正則表示式相對應
>>> re.findall(r"(a)b(c)","abcabcabc")
[('a', 'c'), ('a', 'c'), ('a', 'c')]
>>> add = 'https://www.net.com.edu//action=?asdfsd and other https://www.baidu.com//a=b'
>>> res = re.findall(r'((w{3}\.)(\w+\.)+(com|edu|cn|net))',add)
>>> print(res)
[('www.net.com.edu', 'www.', 'com.', 'edu'), ('www.baidu.com', 'www.', 'baidu.', 'com')]
3.當正則表示式中只帶有一個圓括號時,返回的列表的元素由所有能成功匹配表示式中圓括
號匹配的內容組成,並且該列表中的元素都是字串,它的內容與括號中的正則表示式相對
應。(注意:列表中的字串只是圓括號中的內容,不是整個正則表示式所匹配的內容。)
>>> re.findall(r"(a)bc","abcabcabc")
['a', 'a', 'a']
>>> res = re.findall(r'.*?(\d+).*?','adsd12343.jl34d5645fd789')
>>> print(res)
['12343', '34', '5645', '789']
re.finditer(pattern, string, flags=0)方法
和findall函式一樣,匹配字串中所有滿足的子串,只是返回的是迭代器,而不是存有所有結果的list,這個迭代器裡面存的是每一個結果的匹配物件,這樣可以節省空間,一般用在需要匹配大量的結果情況下
引數說明:
pattern:匹配的正則表示式
string:被匹配的字串
flags:標誌位,用於控制正則表示式的匹配方式,如是否區分大小寫,是否匹配多行等
#匹配字串中所有連續字母組成的子串
#encoding=utf-8
import re
for i in re.finditer(r'[A-Za-z]+','one12two34three56four'):
print(i.group())
re.split(pattern, string, maxsplit=0, flags=0)方法
分割字串,將字串用給定的正則表示式匹配的字串進行分割,分割後返回結果list
引數說明:
pattern:匹配的正則表示式
string:被分割的字串
maxsplit:最大的分割次數
flags:標誌位,用於控制正則表示式的匹配方式。如是否區分大小寫、是否多行匹配等
>>> re.split(r"\d+","one1two2three3four4") #不指定分割次數
['one', 'two', 'three', 'four', '']
>>> re.split(r"\d+","one1two2three3four4",2) #指定分割次數
['one', 'two', 'three3four4']
>>> s = "a 2 b 2 c 5 d" #切割出字母
>>> re.split(r"\s+\d\s+",s)
['a', 'b', 'c', 'd']
re.sub(pattern, repl, string, count=0, flags=0)方法
使用repl替換string中每一個匹配的子串後返回替換後的字串。
引數說明:
pattern:匹配的正則表示式
repl:用於替換的字串
string:要被替換的字串
count:替換的次數,如果為0表示替換所有匹配到的字串,如果是1表示替換1次等,該引數必須是非負整數,預設為0。
flags:標誌位,用於控制正則表示式的匹配方式。如是否區分大小寫、是否多行匹配等。
>>> tel = '13549876489' #將手機號的後四位替換為0
>>> re.sub(r"\d{4}$","0000",tel)
'13549870000'
>>> s = 'num = 0 #a number' #將程式碼後面的註釋去掉
>>> re.sub(r"#.*$","",s)
'num = 0 '
使用mul方法作為repl引數,將匹配的每個數字作為引數傳入到mul函式,處理後將返回結果替換為相應字串
#encoding:utf-8
import re
content="10 20 30 40 50"
def mul(m):
num=int(m.group())
return str(num*2)
result=re.sub("\d+",mul,content)
print (result)
re.subn(pattern, repl, string, count=0, flags=0)方法
與sub函式用法類似,只是有一個額外的特徵,結果返回一個tuple,tuple第一個元素是替換後的新字串,第二個元素是替換的次數
>>> re.subn(r"\d+","","12a34b56c")
('abc', 3)
4.正則修飾符
常用修飾符 |
描述 |
re.I |
全寫(re.IGNORECASE),表示匹配時忽略大小寫 |
re.M |
全寫(re.MULTILINE),多行匹配,影響 ^ 和 $的行 |
re.S |
全寫(re.DOTALL),使點(.)匹配包括換行在內的所有字 |
re.X |
全寫(VERBOSE),忽略模式字串中未轉義的空格和註釋 |
re.I例項:
程式碼示例:預設情況下使用精確匹配文字的大小寫
>>> result=re.match(r"[A-Z]+","asdf12")
>>> print (result)
None
程式碼示例:使用re.I忽略大小寫模式匹配字串
>>> result=re.match(r"[A-Z]+","asdf12",re.I)
>>> print (result)
<_sre.SRE_Match object; span=(0, 4), match='asdf'>
>>> print (result.group())
asdf
re.M例項:
程式碼示例:未使用re.M,會匹配多 行文字的最後一行的結尾
>>> content="""I am a boy\nyou r a beautiful girl\nright"""
>>> re.findall(r"\w+$",content)
['right']
程式碼示例:使用re.M,會匹配多行文字的每行結尾, 也就是遮蔽多行匹配
>>> re.findall(r"\w+$",content,re.M)
['boy', 'girl', 'right']
re.S例項:
程式碼示例:使點(.)匹配包括換行在內的所有字元
>>> s="I am a boy\nyour a girl"
>>> re.search(r".*",s).group()
'I am a boy'
>>> re.search(r".*",s,re.S).group()
'I am a boy\nyour a girl'
re.X例項:
程式碼示例:
import re
pattern=re.compile(r"""\d+ #匹配至少1個連續的數字
\. #匹配點(.)
\d* #匹配數字至少0個""",re.X)
print (pattern.search("test12.58 2.0").group())
#兩個正則表示式是等價的
pattern1=re.compile(r"\d+\.\d*")
print (pattern1.search("test12.58 2.0").group())
結合使用
import re
p=re.compile(r"^.*[a-z]+$",re.I|re.S)
targetString='''I am a Boy
you are a Beautiful Girl
Right'''
result=p.search(targetString)
if result:
print (result.group())
else:
print ("no string found!")