正則表達(dá)式是一種描述性的語(yǔ)言,用來(lái)匹配字符串。凡是符合規(guī)則的字符串,我們認(rèn)為就是匹配了。
正則表達(dá)式并非Python獨(dú)有的,它與語(yǔ)言無(wú)關(guān)。很多語(yǔ)言都支持正則表達(dá)式。
我們經(jīng)常用正則表達(dá)式來(lái)匹配電子郵件、手機(jī)號(hào)碼、url等等。
來(lái)看一個(gè)簡(jiǎn)單的正則表達(dá)式,用于匹配手機(jī)號(hào)碼:
^1[35789]\d{9}$
表示匹配以1開頭,第二位是3或5或7或8或9,后面9位是數(shù)字,且后面必須以9位數(shù)字結(jié)尾。滿足該規(guī)則的手機(jī)號(hào)就說(shuō)明匹配該正則了。
Python里re
模塊包含所有正則表達(dá)式的功能。
注意:由于Python的字符串本身也用\
轉(zhuǎn)義,所以要特別注意:
s = 'ABC\\' # Python的字符串# 對(duì)應(yīng)的正則表達(dá)式字符串變成:'ABC\'
使用Python的r
前綴,就不用考慮轉(zhuǎn)義的問(wèn)題了:
s = r'ABC\' # Python的字符串# 對(duì)應(yīng)的正則表達(dá)式字符串不變:'ABC\'
上面的正則用Python寫則是:
import reres = re.match(r'^1[35789]\d{9}$', '13271222223')print(res)res = re.match(r'^1[35789]\d{9}$', '23271222223')print(res)
輸出:
<_sre.SRE_Match object; span=(0, 11), match='13271222223'>None
發(fā)現(xiàn)第二個(gè)數(shù)字匹配結(jié)果是None
。Python中re
模塊match()
方法判斷是否匹配,如果匹配成功,返回一個(gè)Match對(duì)象,否則返回None
。
所以我們可以寫如下判斷代碼:
import reif re.match(r'^1[35789]\d{9}$', '13271222223'): print('ok')else: print('not match')
輸出:
ok
像\d
屬于元字符。
常用的元字符:
代碼 | 說(shuō)明 |
---|---|
. | 匹配除換行符以外的任意字符 |
\w | 匹配字母或數(shù)字或下劃線或漢字 |
\s | 匹配任意的空白符 |
\d | 匹配數(shù)字 |
\b | 匹配單詞的開始或結(jié)束 |
^ | 匹配字符串的開始 |
$ | 匹配字符串的結(jié)束 |
像{9}
屬于重復(fù)限定符。
常用的限定符:
代碼/語(yǔ)法 | 說(shuō)明 |
---|---|
* | 重復(fù)0次或更多次 |
+ | 重復(fù)1次或更多次 |
重復(fù)0次或1次 | |
{n} | 重復(fù)n次 |
{n,} | 重復(fù)n次或更多次 |
{n,m} | 重復(fù)n到m次 |
[35789]
表示匹配3或5或7或8或9中的某一個(gè)。像[aeiou]
就匹配任何一個(gè)英文元音字母,[.?!]
匹配標(biāo)點(diǎn)符號(hào)(.或?或!)。
像[0-9]
代表的含意與\d
就是完全一致的:一位數(shù)字;同理[a-z0-9A-Z_]
也完全等同于\w
(如果只考慮英文的話)。
re
模塊里的split
可以代替常規(guī)的split
。示例:
# coding: utf-8import restring = 'abc d e'print(string.split(' '))print(re.split(r'\s+', string))
輸出:
['abc', 'd', '', 'e']['abc', 'd', 'e']
我們發(fā)現(xiàn)常規(guī)的切分字符串無(wú)法識(shí)別連續(xù)的空格,但正則可以。
正則表達(dá)式還可以提取子串。用()
表示的就是要提取的分組。
(\d{1,3}\.){3}\d{1,3}
是一個(gè)簡(jiǎn)單的IP地址匹配表達(dá)式。要理解這個(gè)表達(dá)式,可以按順序分析:\d{1,3}
匹配1到3位的數(shù)字,(\d{1,3}\.){3}
匹配三位數(shù)字加上一個(gè)英文句號(hào)(這個(gè)整體也就是這個(gè)分組)重復(fù)3次,最后再加上一個(gè)一到三位的數(shù)字(\d{1,3})
。
import rem = re.match(r'(\d{1,3}\.){3}\d{1,3}', '11.22.33.44')print(m.group(0))print(m.group(1))print(m.groups())
輸出:
11.22.33.4433.('33.',)
group(0)
永遠(yuǎn)是原始字符串,group(1)
、group(2)
……表示第1、2、……個(gè)子串。groups()
返回所有子串的tuple。
這里由于只有一個(gè)分組,所以打印group(2)
會(huì)報(bào)錯(cuò)。
當(dāng)正則表達(dá)式中包含能接受重復(fù)的限定符時(shí),通常的行為是(在使整個(gè)表達(dá)式能得到匹配的前提下)匹配盡可能多的字符。
比如我們要匹配數(shù)字102300后面的0
:
import rem = re.match(r'^(\d+)(0*)$', '102300')print(m.groups())
輸出:
('102300', '')
由于貪婪匹配,\d+
會(huì)一直匹配到末尾,把整個(gè)數(shù)字都匹配了,0*
就只能匹配空字符串了。我們改改:
import rem = re.match(r'^(\d+?)(0*)$', '102300')print(m.groups())
輸出:
('1023', '00')
加個(gè)就可以讓
\d+
采用非貪婪匹配。
懶惰限定符:
代碼/語(yǔ)法 | 說(shuō)明 |
---|---|
*? | 重復(fù)任意次,但盡可能少重復(fù) |
+? | 重復(fù)1次或更多次,但盡可能少重復(fù) |
重復(fù)0次或1次,但盡可能少重復(fù) | |
{n,m}? | 重復(fù)n到m次,但盡可能少重復(fù) |
{n,}? | 重復(fù)n次以上,但盡可能少重復(fù) |
正則表達(dá)式非常強(qiáng)大,本節(jié)只是講解了基礎(chǔ)。更多關(guān)于正則的知識(shí),大家可以找資料學(xué)習(xí)。
參考:
1、正則表達(dá)式30分鐘入門教程
http://deerchao.net/tutorials/regex/regex.htm
聯(lián)系客服