python--正則表達(dá)式

如果不知道正則表達(dá)式是什么俏扩,可以看一下此篇入門文章
關(guān)于正則中的表達(dá)式符號(hào)和特殊字符,可以看此速查表,部分內(nèi)容與python的擴(kuò)展寫法有些出入
自己寫的正則表達(dá)式,也可以用此工具校驗(yàn)一下
python中的一些擴(kuò)展寫法籽前,和速查表的內(nèi)容有出入的

擴(kuò)展寫法.png

常見(jiàn)的正則表達(dá)式屬性.png

該文章所使用的python版本為3.5.2


在python中,是使用re模塊來(lái)支持正則表達(dá)式的敷钾,使用該模塊時(shí)枝哄,直接引入即可

import re

  • match()函數(shù)與search()工作

  • match()函數(shù)試圖從字符串的起始部分對(duì)模式進(jìn)行匹配
  • search()的工作方式與 match()完全一致,不同之處在于 search()會(huì)用它的字符串參數(shù)闰非,在任意位置對(duì)給定正則表達(dá)式模式搜索第一次出現(xiàn)的匹配情況膘格。如果搜索到成功的匹配,就會(huì)返回一個(gè)匹配對(duì)象财松; 否則瘪贱, 返回
m = re.match('foo', 'foo')
if m: print(m.group())  #  輸出為: foo

m = re.match('foo', 'seafood')  # match只能從起始字符串開始匹配的,所以返回m的值為None

m = re.search('foo', 'seafood')
if m: print(m.group())  #  輸出: foo

  • findall()函數(shù)和finditer()函數(shù)

  • findall()查詢字符串中某個(gè)正則表達(dá)式模式全部的非重復(fù)出現(xiàn)情況,返回的是一個(gè)list
  • finditer()與findall()類似辆毡,不過(guò)返回的是一個(gè)迭代器而已
s = 'This and that. the and thirty'
print(re.findall(r'(th\w+) and (th\w+)', s, re.I))  #  輸出: [('This', 'that'), ('the', 'thirty')]

  • sub()函數(shù)和subn()函數(shù)

  • 這兩個(gè)函數(shù)是用于實(shí)現(xiàn)搜索和替換功能
  • subn()和 sub()作用一樣菜秦,sub()返回替換后的字符串,但 subn()還返回一個(gè)表示替換的總數(shù)舶掖,替換后的字符串和表示替換總數(shù)的數(shù)字一起作為一個(gè)擁有兩個(gè)元素的元組返回球昨。
ret = re.sub('X', 'Mr.Smith', 'attn: X\n\nDear X, \n')
print(ret)  #  'attn: Mr.Smith\n\nDear Mr.Smith, \n'

ret = re.subn('X', 'Mr.Smith', 'attn: X\n\nDear X, \n')
print(ret)  #  ('attn: Mr.Smith\n\nDear Mr.Smith, \n', 2)

  • split()函數(shù)

e 模塊和正則表達(dá)式的對(duì)象方法 split()對(duì)于相對(duì)應(yīng)字符串的工作方式是類似的,但是與分割一個(gè)固定字符串相比眨攘,它們基于正則表達(dá)式的模式分隔字符串主慰,為字符串分隔功能添加一些額外的威力

DATA = (
    'Mountain View, CA 94040',
    'Sunnyvale, CA',
    'Los Altos, 94023',
    'Cupertino 95014',
    'Palo Alto CA',
)
for datanum in DATA:
    s = re.split(', |(?= (?:\d{5}|[A-Z]{2})) ', datanum)  # 依據(jù)城市名或者編碼拆分嚣州,正則的含義:依據(jù)", "(逗號(hào)空格)拆分或者依據(jù)空格(該空格的左側(cè)是5個(gè)數(shù)字或者是2個(gè)大寫字母)
    print(s)

結(jié)果:
['Mountain View', 'CA', '94040']
['Sunnyvale', 'CA']
['Los Altos', '94023']
['Cupertino', '95014']
['Palo Alto', 'CA']

  • 一些示例

簡(jiǎn)單的郵箱地址匹配

patt = '\w+@(\w+\.)?\w+\.com'  # 只能匹配@后面,類似于xxx.com/xxxx.yyy.com的郵箱
m = re.match(patt, 'nobody@xxx.yyy.com')

patt = '\w+@(\w+\.)*\w+\.com'  # 匹配@后面有多個(gè)域名的郵箱共螺,類似xxx.xxx.xxx.xxx...com
m = re.match(patt, 'nobody@xxx.yyy.zzz.com')

group()函數(shù)的一些示例

re.match('(ab)', 'ab')  # group()==group(1) 相等
re.match('(a)(b)', 'ab') # group():ab  group(1):a  group(2):b
re.match('(a(b))', 'ab') # group():ab  group(1):ab group(2):b
re.match('((a)(b))', 'ab') # group():ab  group(1):ab  group(2):a goup(3):b

m = re.search(r'\bthe', 'bite the dog')  # \b匹配的是單詞邊界
m = re.search(r'the\b', 'bitethe dog')
m = re.search(r'\Bthe', 'bitethe dog')  # 匹配左側(cè)沒(méi)有邊界的the

使用re.x編寫易于查看的正則表達(dá)式

# 編寫易于查看的正則表達(dá)式
# re.X/VERBOSE 標(biāo)記非常有趣该肴;該標(biāo)記允許用戶通過(guò)抑制在正則表達(dá)式中使用空白符(除了在字符類中或者在反斜線轉(zhuǎn)義中)來(lái)創(chuàng)建更易讀的正則表達(dá)式
m = re.search(r'''(?x)
\((\d{3})\)
[ ]
(\d{3})
-
(\d{4})
''', '(800) 555-1212')  # 其實(shí)和這個(gè)等價(jià)了m = re.search(r'\((\d{3})\)[ ](\d{3})-(\d{4})','(800) 555-1212'),但是更易于看

# 還可以使用\N藐不,其中 N 是在替換字符串中使用的分組編號(hào)
# 將 2/20/91  換成  1991-02-20
m = re.sub(r'(\d{1,2})/(\d{1,2})/(\d{2}|\d{4})', r'19\3-0\1-\2', '2/20/91')

指定group()分組的名稱

# (?P<name>) 和 (?P=name)
# 前者通過(guò)使用一個(gè)名稱標(biāo)識(shí)符而不是使用從 1 開始增加到 N 的增量數(shù)字來(lái)保存匹配匀哄,
# 如果使用數(shù)字來(lái)保存匹配結(jié)果,我們就可以通過(guò)使用\1,\2 ...,\N \來(lái)檢索,  可以查看上一個(gè)示例
# 大概意思就是: 原來(lái)的分組雏蛮,默認(rèn)的用group(1),group(2)...去取結(jié)果涎嚼,現(xiàn)在用group('xxx')去取
m = re.search(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?:\d{4})', '(900) 555-1212 abc (600) 666-9898')
print(m.groupdict())  # 輸出: {'areacode': '900', 'prefix': '555'}
print(m.group())  # 輸出: (900) 555-1212
print(m.group(1), m.group('areacode'))  # 輸出:900 900

m = re.sub(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(\d{4})', r'\g<areacode> \g<prefix>-xxxx', '(900) 666-1212')
print(m)  # 輸出: 900 666-xxxx
m = re.sub(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(\d{4})', r'\1 \2-xxxx', '(900) 666-1212')  # 與上面的等價(jià)
print(m)

指定分組名,并且易于查看的正則表達(dá)式

# 下面這種寫法挑秉,太長(zhǎng)法梯,看著太費(fèi)勁
m = re.match(
    r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?P<number>\d{4}) (?P=areacode)-(?P=prefix)-(?P=number) 1(?P=areacode)(?P=prefix)(?P=number)',
    '(800) 555-1212 800-555-1212 18005551212')
print(bool(m))
# 使用(?x)優(yōu)化
m = re.match(r'''(?x)
# 匹配 (800) 555-1212
\((?P<areacode>\d{3})\)[ ](?P<prefix>\d{3})-(?P<number>\d{4})

# 匹配空格
[ ]

# 匹配 800-500-1212
(?P=areacode)-(?P=prefix)-(?P=number)

# 匹配空格
[ ]

#匹配18005551212
1(?P=areacode)(?P=prefix)(?P=number)
''', '(800) 555-1212 800-555-1212 18005551212')
print(bool(m))

一串?dāng)?shù)字,每三個(gè)之間加上一個(gè)分隔符

# 給一串?dāng)?shù)字衷模,每三位添加一個(gè)'-'
data = '1234567890'
patt = r'((?<=\d)\d{3})+\b'
m = re.search(patt, data)
while m:
    data = data[:m.start()] + '-' + data[m.start():]
    m = re.search(patt, data)
print('添加"-"完畢鹊汛,結(jié)果為:', data)

識(shí)別時(shí)間

# 左邊不能是數(shù)字,右邊也不能是數(shù)字
patt = r'(?<!\d)(2[0-3]{1}|[01]?[0-9]{1}):([0-5]?[0-9]{1}):([0-5]?[0-9]{1})(?!\d)'
m = re.search(patt, 'asc 19:23:23 adfs')
print(m.group(1), m.group(2), m.group(3))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末阱冶,一起剝皮案震驚了整個(gè)濱河市刁憋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌木蹬,老刑警劉巖至耻,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異镊叁,居然都是意外死亡尘颓,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門晦譬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)疤苹,“玉大人,你說(shuō)我怎么就攤上這事敛腌∥酝粒” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵像樊,是天一觀的道長(zhǎng)尤莺。 經(jīng)常有香客問(wèn)我,道長(zhǎng)生棍,這世上最難降的妖魔是什么颤霎? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上友酱,老公的妹妹穿的比我還像新娘晴音。我一直安慰自己,他們只是感情好粹污,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布段多。 她就那樣靜靜地躺著,像睡著了一般壮吩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上加缘,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天鸭叙,我揣著相機(jī)與錄音,去河邊找鬼拣宏。 笑死沈贝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的勋乾。 我是一名探鬼主播宋下,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼辑莫!你這毒婦竟也來(lái)了学歧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤各吨,失蹤者是張志新(化名)和其女友劉穎枝笨,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揭蜒,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡横浑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屉更。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片徙融。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瑰谜,靈堂內(nèi)的尸體忽然破棺而出欺冀,到底是詐尸還是另有隱情,我是刑警寧澤似舵,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布脚猾,位于F島的核電站,受9級(jí)特大地震影響砚哗,放射性物質(zhì)發(fā)生泄漏龙助。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望提鸟。 院中可真熱鬧军援,春花似錦、人聲如沸称勋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赡鲜。三九已至空厌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間银酬,已是汗流浹背嘲更。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揩瞪,地道東北人赋朦。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像李破,于是被迫代替她去往敵國(guó)和親宠哄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容