一直在糾結自己的博客到底應該寫一些什么東西,這幾天發現自己的正則用的不是很熟練,於是想要寫一篇關於正則表達式的博客,目的就是為了讓自己以后要用而又不會的時候不至於像無頭蒼蠅一樣到處亂撞。
有些人在碰到問題時,就像:“我知道,我可以使用正則表達式。”現在,他們就有了兩個問題。(Jamie “jwz” Zawinski,1997年8月 Netscape和Mozilla.org的創始人之一)
jwz所說的兩個問題:一個就是要解決的問題,一個就是如何使用正則表達式解決問題------這本身就是個問題了,由此可見學會並熟練使用正則表達式是多么的重要~~~
因為我主要是使用Python,所以先說明在Python中是通過re模塊來支持正則表達式。
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()說起
使用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個數字的空格用','分割開
