一個關於Python正則表達式的快速使用手冊

一直在糾結本身的博客到底應該寫一些什麼東西,這幾天發現本身的正則用的不是很熟練,因而想要寫一篇關於正則表達式的博客,目的就是爲了讓本身之後要用而又不會的時候不至於像無頭蒼蠅同樣處處亂撞。正則表達式

 

有些人在碰到問題時,就像:「我知道,我可使用正則表達式。」如今,他們就有了兩個問題。(Jamie 「jwz」 Zawinski,1997年8月  Netscape和Mozilla.org的創始人之一)函數

jwz所說的兩個問題:一個就是要解決的問題,一個就是如何使用正則表達式解決問題------這自己就是個問題了,因而可知學會並熟練使用正則表達式是多麼的重要~~~spa

由於我主要是使用Python,因此先說明在Python中是經過re模塊來支持正則表達式。code

re模塊中有許多強大的方法:對象

函數/方法 描述
compile(pattern,flags=0) 使用任何可選的標記來「編譯」正則表達式模式,返回一個正則表達式對象
match(pattern,string,flags=0) 嘗試使用正則表達式匹配字符串,若是匹配成功,就返回匹配對象,若是失敗就返回None
search(pattern,string,flags=0) 使用可選標記搜索字符串中第一次出現的正則表達式模式,若是匹配成功就返回匹配對象,若是失敗就返回None
findall(pattern,string[,flags]) 查找字符串中全部(非重複)出現的正則表達式模式,返回一個匹配列表
finditer(pattern,string[,flags]) 與fandall相同,但返回的不是列表,而是一個迭代器。每一次迭代返回一個正則表達式對象
split(pattern,string,max=0) 根據正則表達式的模式分隔符,將字符串分割爲列表,而後返回成功匹配的列表,分割最多操做max次(默認是分割全部)
sub(pattern,repl,string,count=0) 使用repl替換正則在字符串中匹配到的位置,除非自定義count,不然就替換全部匹配到的位置
purge() 清除隱式編譯的正則表達式模式
group(num=0) 返回整個匹配對象,或者編號爲num的子組
groups(default=None) 返回一個包含全部匹配子組的元組,若是沒有匹配到就返回空元組
groupdic(default=None)  返回一個包含全部匹配的命名子組的字典,全部的子組名稱做爲字典的key,若是沒有匹配到就返回一個空字典

compile()函數是用來編譯正則表達式的,因此從match()提及blog

使用match()方法匹配字符串

>>> import re
>>> m = re.match('foo','foo')
>>> m.group()                  #使用group()方法返回匹配結果
'foo'

#證實匹配失敗返回None
>>> m = re.match('foo','fll')
>>> m.group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

None類型沒有group屬性,就是說m是None

#match是從字符串開始部分匹配,也就是f對應f,o對應o,因此匹配成功
>>> re.match('foo','food').group()
'foo'
#而這個例子裏從開始匹配的話,f對應s,因此匹配失敗
>>> re.match('foo','sfood').group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

上述例子中foo匹配sfood失敗,但foo卻實實在在存在於sfood中,這裏就要用search()使用搜索而不是去匹配字符串

>>> m = re.search('foo','sfood')
>>> m.group()
'foo'

group()與groups()的使用示例:

>>> m = re.match('(\w\w\w)-(\d\d\d)','abc-123')
>>> m.group()
'abc-123'
>>> m.group(1)
'abc'
>>> m.group(2)
'123'
>>> m.groups()  #groups只匹配子組,也就是加()的那些內容
('abc', '123')

匹配郵箱的示例:

>>> re.match('\w+@\w+\.com','awmpy@qq.com').group()
'awmpy@qq.com'

findall()和finditer()的使用示例:

>>> s = 'This and that'
>>> re.findall(r'(th\w+)',s,re.I)
['This', 'that']  #findall返回的就是列表
>>> it = re.finditer(r'(th\w+)',s,re.I)  #生成一個迭代器
>>> g = it.__next__() 
>>> g.groups()
('This',)         #groups返回值是一個元組,g每次迭代取一個值
>>> g.group(1)
'This'
>>> g = it.__next__()
>>> g.groups()
('that',)
>>> g.group(1)
'that'
>>> [g.group(1) for g in re.finditer(r'(th\w+)',s,re.I)]  #使用列表解析造成列表
['This', 'that']
>>> 

 sub()和subn()函數使用示例:

>>> re.sub('[ae]','X','abcdef')
'XbcdXf'
>>> re.subn('[ae]','X','abcedf')
('XbcXdf', 2)
>>> 

split()函數的使用

re.split()實際上在Python中str對象也有split屬性,可是re.split的存在就是由於他能夠結合re的擴展匹配,完成比較複雜的分割博客

>>> import re
>>> DATA = {
...     'Mountain View, CA 94040',
...     'Sunnyvale, CA',
...     'Los Altos, 94606',
...     'Cupertino 95401',
...     'Palo Alto CA',
... }
>>> for item in DATA:
...     print(re.split(', |(?= (?:\d{5}|[A-Z]{2})) ', item))
... 
['Mountain View', 'CA', '94040']
['Cupertino', '95401']
['Sunnyvale', 'CA']
['Los Altos', '94606']
['Palo Alto', 'CA']
>>> 
#使用正向前視斷言將','還有後邊是兩個大寫字母和5個數字的空格用','分割開
相關文章
相關標籤/搜索