一、最常用的匹配語法
re.match 從頭開始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.split 以匹配到的字符當做列表分隔符
re.sub 匹配字符並替換
'.'
默認匹配除\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
匹配字符開頭,若指定flags MULTILINE,這種也可以匹配上(r
"^a"
,
"\nabc\neee"
,flags
=
re.MULTILINE)
'$'
匹配字符結尾,或e.search(
"foo$"
,
"bfoo\nsdfsf"
,flags
=
re.MULTILINE).group()也可以
'*'
匹配
*
號前的字符
0
次或多次,re.findall(
"ab*"
,
"cabb3abcbbac"
) 結果為[
'abb'
,
'ab'
,
'a'
]
'+'
匹配前一個字符
1
次或多次,re.findall(
"ab+"
,
"ab+cd+abb+bba"
) 結果[
'ab'
,
'abb'
]
'?'
匹配前一個字符
1
次或
0
次
'{m}'
匹配前一個字符m次
'{n,m}'
匹配前一個字符n到m次,re.findall(
"ab{1,3}"
,
"abb abc abbcbbb"
) 結果
'abb'
,
'ab'
,
'abb'
]
'|'
匹配|左或|右的字符,re.search(
"abc|ABC"
,
"ABCBabcCD"
).group() 結果
'ABC'
'(...)'
分組匹配,re.search(
"(abc){2}a(123|456)c"
,
"abcabca456c"
).group() 結果 abcabca456c
'\Z'
匹配字符結尾,同$
'\d'
匹配數字
0
-
9
'\D'
匹配非數字
'\w'
匹配[A
-
Za
-
z0
-
9
]
'\W'
匹配非[A
-
Za
-
z0
-
9
]
's'
匹配空白字符、\t、\n、\r , re.search(
"\s+"
,
"ab\tc1\n3"
).group() 結果
'\t'
'(?P<name>...)'
分組匹配 re.search(
"(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})"
,
"371481199306143242"
).groupdict(
"city"
) 結果{
'province'
:
'3714'
,
'city'
:
'81'
,
'birthday'
:
'1993'
}
import re
a = 'abc+10 + 20'
b = 'abc+10+20'
regex1 = re.compile('\d+\s*[+]\s*\d+') #對正則表達式進行編譯,\d+表示匹配一個或多個數字,\s*表示匹配0個或多個空格,[]里面為字符集
print(regex1.search(a).group()) #匹配字符串 結果:10 + 20,對匹配該算術表達式來說,如果這里換成\s+則匹配不到,如果\d+換成\d*則會匹配到你不想匹配到的結果
print(regex1.search(b).group()) #結果:10+20
上述的python表示方式也可以這么表示
print(re.search('\d+\s*[+]\s*\d+',a).group())等同於先進行編譯,再匹配
3、?一般搭配*、+、{}使用
當正則表達式中包含能接受重復的限定符時,通常的行為是(在使整個表達式能得到匹配的前提下)匹配盡可能多的字符。以這個表達式為例:a.*b,它將會匹配最長的以a開始,以b結束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱為貪婪匹配。
有時,我們更需要懶惰匹配,也就是匹配盡可能少的字符。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它后面加上一個問號?。這樣.*?就意味着匹配任意數量的重復,但是在能使整個匹配成功的前提下使用最少的重復。現在看看懶惰版的例子吧:
a.*?b匹配最短的,以a開始,以b結束的字符串。如果把它應用於aabab的話,它會匹配aab(第一到第三個字符)和ab(第四到第五個字符)。
python結果:
a = 'aabab'
regex1 = re.compile(r'a.*?b')
regex2 = re.compile(r'a.*b')
print(regex1.findall(a)) ->['aab', 'ab'] ->這里用search的話只能找到aab
print(regex2.findall(a)) ->['aabab']
"*?" 重復任意次,但盡可能少重復
如 "acbacb" 正則 "a.*?b" 只會取到第一個"acb" 原本可以全部取到但加了限定符后,只會匹配盡可能少的字符 ,而"acbacb"最少字符的結果就是"acb"
"+?" 重復1次或更多次,但盡可能少重復
與上面一樣,只是至少要重復1次
"??" 重復0次或1次,但盡可能少重復
如 "aaacb" 正則 "a.??b" 只會取到最后的三個字符"acb"
"{n,m}?" 重復n到m次,但盡可能少重復
如 "aaaaaaaa" 正則 "a{0,m}" 因為最少是0次所以取到結果為空
"{n,}?" 重復n次以上,但盡可能少重復
如 "aaaaaaa" 正則 "a{1,}" 最少是1次所以取到結果為 "a"
4、groups與()搭配使用
a = 'abc+10+20'
regex1 = re.compile(r'(\d+)([+])(\d+)')
print(regex1.search(a).groups()) ->('10', '+', '20') 能把分組的數據一一取出來
5、^與&
如:匹配以數字開頭以數字結尾
a = '1abc+10+20'
regex1 = re.compile(r'^\d.*\d$')
print(regex1.search(a).group()) ->1abc+10+20,如果不是以數字開頭和數字結尾則匹配不到
6、groupdict與()搭配使用
print(re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict() ) -> {'province': '3714', 'city': '81', 'birthday': '1993'}
7、split使用
- a = '1abc+10+20'
- regex1 = re.compile(r'\+')
- print(regex1.split(a)) ->['1abc', '10', '20']
上述2、3步驟相當於
print(re.split(r'\+',a))
8、sub使用
*號替換+號
- a = '1abc+10+20'
- regex1 = re.compile(r'\+')
- print(regex1.sub('*',a)) ->1abc*10*20,后面可以加count來確保匹配多少次
上述2、3步驟相當於
#print(re.sub(r'\+','*',a)) ->1abc*10*20
9、反斜杠的困擾
與大多數編程語言相同,正則表達式里使用"\"作為轉義字符,這就可能造成反斜杠困擾。假如你需要匹配文本中的字符"\",那么使用編程語言表示的正則表達式里將需要4個反斜杠"\\\\":前兩個和后兩個分別用於在編程語言里轉義成反斜杠,轉換成兩個反斜杠后再在正則表達式里轉義成一個反斜杠。Python里的原生字符串很好地解決了這個問題,這個例子中的正則表達式可以使用r"\\"表示。同樣,匹配一個數字的"\\d"可以寫成r"\d"。有了原生字符串,你再也不用擔心是不是漏寫了反斜杠,寫出來的表達式也更直觀。
10^與[]搭配
[^abc]匹配除了abc之外的任意字符
最后在添加一個圖表
