天天看點

正規表達式 整理(\w \s \d 點 貪婪比對 非貪婪比對 * + ? {} | [] ^ $ \b 單詞邊界 分組、re.findall()、re.split()、re.search()、re.match()、re.compile()、re.sub())

re.findall  比對到正規表達式的字元,比對到的每個字元存入一個清單,傳回一個比對到的所有字元清單

一. 比對單個字元
import re
# \w 比對所有字母、數字、下劃線
re.findall('\w','abcd_123    *-')
# 結果為:['a', 'b', 'c', 'd', '_', '1', '2', '3']


# \s 比對所有不可見字元
#  不可見字元有:\n \t 空格
re.findall('\s','abcd \n\tdf21  ')
# 結果為:[' ', '\n', '\t', ' ', ' ']


# \d 比對所有數字
re.findall('\d','a1bc3 4d \n\tdf21  ')
# 結果為:['1', '3', '4', '2', '1']


# . 比對\n換行符以外的所有可見和不可見字元
re.findall('.', 'c3 d\n\td1')
# 結果為:['c', '3', ' ', 'd', '\t', 'd', '1']      
二. 比對多個字元
#比對多個字元:* + ?
import re
#  * 比對0或n次
re.findall('\d*', '1a23')
# 結果為:['1', '', '23', '']


#  + 比對1或n次
re.findall('\d+', '1a23')
# 結果為:['1', '23']
#前面2個是叫貪婪比對


#  ? 比對0或1次
re.findall('\d?', '1a3')
# 結果為:['1', '', '3', '']
# 這個叫非貪婪比對      
三. 比對指定範圍字元
# {m,n} 比對最少m次,最多n次
# {m} 隻比對m次的
# {,n}  比對最大n次,最小次數不限
# {m,}  比對最小m次,最大次數不限
re.findall('\d{2,4}', '1a33g134nn12345')
# 結果為:['33', '134', '1234']
re.findall('a{3}', '1aaa3*G+1aaaan#b')
# 結果為:['aaa', 'aaa']


# | 比對 或 文法的字元
re.findall('1|23|4', '1a33g134nn12345')
# 結果為:['1', '1', '4', '1', '23', '4']


# [ ] 比對括号内的字元(隻比對單個)
re.findall('[123]', '1a33g134nn12345')
# 結果為:['1', '3', '3', '1', '3', '1', '2', '3']
re.findall('[0-9a-zA-Z]', '1a3*G+1n#')
# 比對0到9或者a到z或者A到Z單個字元
# 結果為:['1', 'a', '3', 'G', '1', 'n']


# ^x 行首比對
# x$ 行尾比對
re.findall('^1', '1a3*G+1n#b')
re.findall('b$', '1a3*G+1n#b')
# 結果為:['1']     
# 結果為:['b']      
四. 一些比較不常見的比對

\b 單詞邊界,重點了解在于‘邊界’二字,‘單詞’代表比對的字元串

  劃定邊界基本原則:比如表達式為 '\b單詞\b'   的意思就是比對字元串為‘單詞’,單詞兩邊需要存在滿足條件的邊界才能比對成功。比對失敗結果肯定是空清單,比對成功結果就是比對的單詞字元串清單。

  \b在哪邊就限制哪邊的比對。

  比對成功的邊界滿足條件跟比對單詞字元串有關聯,雙方是同一類型則失敗,不同類型則成功

# 正規表達式中的\b可以用比對目标單詞字元串,加設限制比對邊界
# 單詞的 前邊界:'\b單詞'
#     後邊界:'單詞\b'
#     前和後邊界:'\b單詞\b'
# 在\b的使用中有這樣幾點是需要格外注意的。
# 0. \b本身的含義就有轉義字元串的作用,要用字元邊界就得将其原始含義去掉,是以需要加r或者\\b(兩個不能一起用)

# 1. 單詞字元串能否比對成功是有規律的:
# 如果是a-z,A-Z,0-9,則比對邊界為非字母數字才能比對成功。
# 如果是非字母數字,則比對邊界為a-z,A-Z,0-9才能比對成功。
# 如果是兩個混在一起,判斷标準為那個挨着\b最近的字元作為判斷标準,如果是字母數字,則比對邊界為非字母數字才成功,反之亦然。
import re
s='aa abcperty/-aa '
res1=re.findall(r'\babc',s)    # 結果:['abc'] 單詞為字母,左比對邊界為非字母數字,比對成功
res2=re.findall(r'abc\b',s)    # 結果:[]      單詞為字母,右比對邊界為字母,比對失敗
print(res1,res2)

s='aa@# perty/-aa '
res3=re.findall(r'\b@#',s)     # 結果:['@#']  單詞為非字母數字,左比對邊界為字母,比對成功
res4=re.findall(r'@#\b',s)     # 結果:[]      單詞為非字母數字,右比對邊界為空格(非字母數字),比對失敗
print(res3,res4)

s='aa@a perty/-aa '
res5=re.findall(r'\b@a',s)     # 結果:['@a']  單詞為混合,@挨着\b,單詞以非字母數字為标準,左比對邊界為字母,比對成功
res6=re.findall(r'@a\b',s)     # 結果:['@a']  單詞為混合,a挨着\b,單詞以字母數字為标準,右比對邊界為空格,比對成功
print(res5,res6)

# 2.字元串的首尾邊界預設定義為 非字母數字,是以如果比對的單詞字元串在首尾,則比對字母數字則會成功,比對非字母數字失敗。
s= 'abcd@'
res7 = re.findall(r'\ba',s)    # 結果:['a'] 單詞為字母,左比對邊界為首,預設定義為非字母數字,比對成功
res8 = re.findall(r'@\b',s)    # 結果:[] 單詞為非字母數字,右比對邊界為尾,預設定義為非字母數字,比對失敗
print(res7,res8)      
五. 分組

用小括号表示,分組後的正規表達式優先比對并傳回括号内的值

六. re子產品常用方法

re.search   

查找,比對成功傳回第一比對的字元串,結果為封裝的對象(注意search傳回的是個對象,.group() 後得到的是字元串不是清單),失敗傳回None

import re
s = 'welcome world hello python'
res = re.search('hello', s)
print(res)
print(res.group())

# 結果:
<_sre.SRE_Match object; span=(14, 19), match='hello'>
hello      

re.match

比對,在行首比對字元串,方法同search,差別在于,match在行首比對,search是從前到後全部查找比對。

s = 'hello welcome world hello python'
res=re.match('hello', s)
print(res)
print(res.group())
res1=re.match('welcome',s)
print(res1)

# 結果:
<_sre.SRE_Match object; span=(0, 5), match='hello'>
hello
None      

re.split 

用比對成功的字元串作為切割符,進行原字元串的切割,傳回一個切割後的清單。比對失敗,直接傳回原字元串,不做任何切割處理

比對成功完成切割
s1 = 'hello welchhome world hello python'
res=re.split('h.+?o',s1)
print(res)

# 結果:
['', ' welc', 'me world ', ' python']

比對不成功,傳回原字元串。不做任何切割處理
s1 = 'hello welchhome world hello python'
res0=re.findall('json',s1)
print(res0)
res=re.split('json',s1)
print(res)

# 結果:
[]
['hello welchhome world hello python']      

 re.compile

将正規表達式封裝成對象,用于重複使用該表達式。使用方法看例子:

s1 = 'hello welchhome world hello python'
pat=re.compile('h.+?o')
res2=pat.findall(s1)
print(res2)

# 結果:
['hello', 'hho', 'hello']      

re.sub

替換,重組(group(1)、group(2)...group(n)用\1  \2  ...\n來替換,進行字元串的重新組合(前面要加r防止其轉義))

s='<我的部落格位址https://www.cnblogs.com/oldboy2019/,歡迎大家來通路、交流,歡迎大家一起探讨python!ohye!>'
# pat=re.compile(r'<(.+)http://(www.+/),.+>')
pat=re.compile(r'<(.+)http.+(www.+/),(.+?)([a-z]+)!(.+)!>')
print(pat.findall(s))
res=pat.sub(r'\2\n這是\1,\4,\5\3',s)
print(res)

# 結果:
[('我的部落格位址', 'www.cnblogs.com/oldboy2019/', '歡迎大家來通路、交流,歡迎大家一起探讨', 'python', 'ohye')]
www.cnblogs.com/oldboy2019/
這是我的部落格位址,python,ohye歡迎大家來通路、交流,歡迎大家一起探讨

#注意,這裡第二個列印我在前面加了個原義字元r,但是裡面\n還是轉義成了換行,很奇怪,這個地方歡迎一起交流,為何會出現這種情況呢?      
請相信自己

當我們迷茫,懶惰,退縮的時候

我們會格外的相信命運

相信一切都是命中注定

而當我們努力拼搏,積極向上時

我們會格外的相信自己

是以命運是什麼呢?

它是如果你習慣它

那它就會一直左右你

如果你想掙脫它

那它就成為你的阻礙

可如果你打破了它

那它就是你人生的墊腳石!

如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,部落客在此感謝!