正則表達式

正則表達式(RegularExpression,re)

  • 匹配符合某個規(guī)則的字符串
  • 常用于檢索魔眨,替換某些模式的文本

正則的寫法

  • \d:任意一個數(shù)字殉簸,等價于 [0-9]
  • \D:匹配任意非數(shù)字
  • \s:匹配任意空白字符,等價于 [\t\n\r\f]
  • \S:匹配任意非空字符
  • \w:字母票摇、數(shù)字、下劃線,a-z左腔,A-Z,0-9捅儒,_
  • \W:除了字母液样、數(shù)字、下劃線巧还,a-z鞭莽,A-Z,0-9麸祷,_
  • \A:匹配字符串開始
  • \z:匹配字符串結(jié)束
  • \Z:匹配字符串結(jié)束澎怒,如果是存在換行,只匹配到換行前的結(jié)束字符
  • ^:匹配字符串的開始
  • $:匹配字符串的結(jié)尾
  • .(點號):表示任意一個字符阶牍,除了\n喷面,比如查找所有的一個字符 \.
  • [...]:匹配中括號中列舉的任意字符,[amk] 匹配 'a'荸恕,'m'或'k'
  • [^...]:不在[ ]中的字符乖酬,[^abc] 匹配除了a,b,c之外的字符
  • *:表示前面的內(nèi)容重復(fù)零次或多次
  • +:前面的內(nèi)容至少出現(xiàn)一次
  • ?:前面的內(nèi)容出現(xiàn)一次或零次
  • {m,n}:前面的內(nèi)容出現(xiàn)最最少m次融求,最多n次
  • a| b:匹配a或b
  • (re):對正則表達式分組并記住匹配的文本

示例:

  • 驗證一個數(shù)字:^\d$
  • 至少一個數(shù)字:^\d+$
  • 5-10位數(shù)字:^\d{5-10}$
  • 16以上咬像,99以下:^[16-99]$
  • 英文字符和數(shù)字:^[A-Za-z0-9]$

使用步驟:

  1. 使用compile將表示正則的字符串編譯為一個pattern對象
  2. 通過pattern對象提供的一系列方法對文本進行查找匹配,該對象擁有一系列方法用于正則表達式匹配和替換生宛,獲得匹配結(jié)果县昂,一個Match對象
  3. 最后使用Match對象提供的屬性和方法獲得信息,根據(jù)需要進行操作

貪婪和非貪婪

  • 貪婪:盡可能多的匹配陷舅,(*)表示貪婪匹配
  • 非貪婪:找到符合條件的最小內(nèi)容即可倒彰,(?)表示非貪婪

re.match函數(shù)

re.match 嘗試從字符串的起始位置匹配一個模式,匹配成功re.match方法返回一個匹配的對象莱睁,否則返回None待讳。如果不是起始位置匹配成功的話芒澜,match()返回none。

函數(shù)語法:

re.match(pattern,string,flags=0)

函數(shù)參數(shù)說明

參數(shù) 描述
pattern 匹配的正則表達式
string 要匹配的字符串
flags 標志位创淡,用于控制正則表達式的匹配方式痴晦,如:是否區(qū)分大小寫,多行匹配等等琳彩。

正則表達式可以包含一些可選標志修飾符來控制匹配的模式誊酌。修飾符被指定為一個可選的標志。多個標志可以通過按位 OR(|) 它們來指定露乏。如 re.I | re.M 被設(shè)置成 I 和 M 標志:

修飾符 描述
re.I 使匹配對大小寫不敏感
re.M 多行匹配碧浊,影響 ^ 和 $
re.S 使 . 匹配包括換行在內(nèi)的所有字符
re.U 根據(jù)Unicode字符集解析字符。這個標志影響 \w, \W, \b, \B.

可以使用group(num) 或 groups() 匹配對象函數(shù)來獲取匹配表達式瘟仿。

匹配對象方法 描述
group(num=0) 匹配的整個表達式的字符串箱锐,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應(yīng)值的元組猾骡。
groups() 返回一個包含所有小組字符串的元組瑞躺,從 1 到 所含的小組號敷搪。

代碼示例:

# 導(dǎo)入相關(guān)包
import re

print(re.match('www', 'www.runoob.com'))  # 在起始位置匹配
print(re.match('www', 'www.runoob.com').span())
print(re.match('com', 'www.runoob.com'))    # 不在起始位置匹配

line = "Cats are smarter than dogs"
 # r表示字符串不轉(zhuǎn)義
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)

if matchObj:
   print('matchObj.group():',matchObj.group())
   print('matchObj.group():',matchObj.groups())
   print('matchObj.group(1):',matchObj.group(1))
   print('matchObj.group(2):',matchObj.group(2))
else:
   print('No match!!')

運行結(jié)果為:

<re.Match object; span=(0, 3), match='www'>
(0, 3)
None
matchObj.group(): Cats are smarter than dogs
matchObj.group(): ('Cats', 'smarter')
matchObj.group(1): Cats
matchObj.group(2): smarter

re.search函數(shù)

re.search 掃描整個字符串并返回第一個成功的匹配兴想。

函數(shù)語法:

re.search(pattern, string, flags=0)

代碼示例:

import re
 
line = "Cats are smarter than dogs";
 
searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)
 
if searchObj:
   print("searchObj.group() : ", searchObj.group())
   print("searchObj.group(1): ", searchObj.group(1))
   print("searchObj.group(2): ", searchObj.group(2))
else:
   print("Nothing found!!")

運行結(jié)果為:

searchObj.group() : Cats are smarter than dogs
searchObj.group(1) : Cats
searchObj.group(2) : smarter

re.match與re.search的區(qū)別

re.match只匹配字符串的開始,如果字符串開始不符合正則表達式赡勘,則匹配失敗嫂便,函數(shù)返回None;而re.search匹配整個字符串闸与,直到找到一個匹配毙替。

代碼示例:

import re
 
line = "Cats are smarter than dogs";
 
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
   print('match --> matchObj.group() :' , matchObj.group())
else:
   print("No match!!")
 
matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
   print("search --> searchObj.group() : ", matchObj.group())
else:
   print("No match!!")

運行結(jié)果為:

No match!!
search --> searchObj.group() : dogs

檢索和替換

Python 的 re 模塊提供了re.sub用于替換字符串中的匹配項。

函數(shù)語法

re.sub(pattern, repl, string, count=0, flags=0)

函數(shù)參數(shù)說明

參數(shù) 描述
pattern 正則中的模式字符串
repl 替換的字符串践樱,也可為一個函數(shù)
string 要被查找替換的原始字符串
count 模式匹配后替換的最大次數(shù)厂画,默認 0 表示替換所有的匹配

代碼示例

import re
 
phone = "2004-959-559 # 這是一個國外電話號碼"
 
# 刪除字符串中的 Python注釋 
num = re.sub(r'#.*$', "", phone)
print("電話號碼是: ", num)
 
# 刪除非數(shù)字(-)的字符串 
num = re.sub(r'\D', "", phone)
print("電話號碼是 : ", num)

運行結(jié)果為:

電話號碼是: 2004-959-559
電話號碼是 : 2004959559

repl 參數(shù)是一個函數(shù)

import re
 
# 將匹配的數(shù)字乘以 2
def double(matched):
    value = int(matched.group('value'))
    return str(value * 2)
 
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))

運行結(jié)果為:

A46G8HFD1134

re.compile函數(shù)

compile 函數(shù)用于編譯正則表達式,生成一個正則表達式( Pattern )對象拷邢,供 match() 和 search() 這兩個函數(shù)使用袱院。

語法格式

re.compile(pattern[, flags])

參數(shù):

  • pattern : 一個字符串形式的正則表達式
  • flags : 可選,表示匹配模式瞭稼,比如忽略大小寫忽洛,多行模式等,具體參數(shù)為:
    • re.I 忽略大小寫
    • re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴于當(dāng)前環(huán)境
    • re.M 多行模式
    • re.S 即為 . 并且包括換行符在內(nèi)的任意字符(. 不包括換行符)
    • re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴于 Unicode 字符屬性數(shù)據(jù)庫
    • re.X 為了增加可讀性环肘,忽略空格和 # 后面的注釋

代碼示例:

>>>import re
>>> pattern = re.compile(r'\d+')                    # 用于匹配至少一個數(shù)字
>>> m = pattern.match('one12twothree34four')        # 查找頭部欲虚,沒有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 2, 10) # 從'e'的位置開始匹配,沒有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 3, 10) # 從'1'的位置開始匹配悔雹,正好匹配
>>> print m                                         # 返回一個 Match 對象
<_sre.SRE_Match object at 0x10a42aac0>
>>> m.group(0)   # 可省略 0
'12'
>>> m.start(0)   # 可省略 0
3
>>> m.end(0)     # 可省略 0
5
>>> m.span(0)    # 可省略 0
(3, 5)

在上面复哆,當(dāng)匹配成功時返回一個 Match 對象欣喧,其中:

  • group([group1, …]) ,方法用于獲得一個或多個分組匹配的字符串梯找,當(dāng)要獲得整個匹配的子串時续誉,可直接使用 group() 或 group(0);
  • start([group]) 初肉,方法用于獲取分組匹配的子串在整個字符串中的起始位置(子串第一個字符的索引)酷鸦,參數(shù)默認值為 0;
  • end([group]) 方法用于獲取分組匹配的子串在整個字符串中的結(jié)束位置(子串最后一個字符的索引+1)牙咏,參數(shù)默認值為 0
  • span([group]) 臼隔,方法返回 (start(group), end(group))

代碼示例

>>>import re
>>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I)   # re.I 表示忽略大小寫
>>> m = pattern.match('Hello World Wide Web')
>>> print m                               # 匹配成功,返回一個 Match 對象
<_sre.SRE_Match object at 0x10bea83e8>
>>> m.group(0)                            # 返回匹配成功的整個子串
'Hello World'
>>> m.span(0)                             # 返回匹配成功的整個子串的索引
(0, 11)
>>> m.group(1)                            # 返回第一個分組匹配成功的子串
'Hello'
>>> m.span(1)                             # 返回第一個分組匹配成功的子串的索引
(0, 5)
>>> m.group(2)                            # 返回第二個分組匹配成功的子串
'World'
>>> m.span(2)                             # 返回第二個分組匹配成功的子串
(6, 11)
>>> m.groups()                            # 等價于 (m.group(1), m.group(2), ...)
('Hello', 'World')
>>> m.group(3)                            # 不存在第三個分組
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: no such group

findall

在字符串中找到正則表達式所匹配的所有子串妄壶,并返回一個列表摔握,如果沒有找到匹配的,則返回空列表丁寄。
注意: match 和 search 是匹配一次氨淌,findall 匹配所有

語法格式

findall(string[, pos[, endpos]])

參數(shù):

  • string : 待匹配的字符串。
  • pos : 可選參數(shù)伊磺,指定字符串的起始位置盛正,默認為 0。
  • endpos : 可選參數(shù)屑埋,指定字符串的結(jié)束位置豪筝,默認為字符串的長度。

代碼示例:

import re
 
pattern = re.compile(r'\d+')   # 查找數(shù)字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
 
print(result1)
print(result2)

輸出結(jié)果:

['123', '456']
['88', '12']

re.finditer

和 findall 類似摘能,在字符串中找到正則表達式所匹配的所有子串续崖,并把它們作為一個迭代器返回。

語法格式:

re.finditer(pattern, string, flags=0)

代碼示例:

import re
 
it = re.finditer(r"\d+","12a32bc43jf3") 
for match in it: 
    print (match.group() )

輸出結(jié)果:

12
32
43
3

re.split函數(shù)

split 方法按照能夠匹配的子串將字符串分割后返回列表团搞,它的使用形式如下:

語法格式:

re.split(pattern, string[, maxsplit=0, flags=0])

參數(shù):

參數(shù) 描述
pattern 匹配的正則表達式
string 要匹配的字符串严望。
maxsplit 分隔次數(shù),maxsplit=1 分隔一次逻恐,默認為 0像吻,不限制次數(shù)。
flags 標志位梢莽,用于控制正則表達式的匹配方式萧豆,如:是否區(qū)分大小寫,多行匹配等等昏名。

代碼示例:


>>>import re
>>> re.split('\W+', 'runoob, runoob, runoob.')
['runoob', 'runoob', 'runoob', '']
>>> re.split('(\W+)', ' runoob, runoob, runoob.') 
['', ' ', 'runoob', ', ', 'runoob', ', ', 'runoob', '.', '']
>>> re.split('\W+', ' runoob, runoob, runoob.', 1) 
['', 'runoob, runoob, runoob.']
 
>>> re.split('a*', 'hello world')   # 對于一個找不到匹配的字符串而言涮雷,split 不會對其作出分割
['hello world']
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市轻局,隨后出現(xiàn)的幾起案子洪鸭,更是在濱河造成了極大的恐慌样刷,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件览爵,死亡現(xiàn)場離奇詭異置鼻,居然都是意外死亡,警方通過查閱死者的電腦和手機蜓竹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門箕母,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人俱济,你說我怎么就攤上這事嘶是。” “怎么了蛛碌?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵聂喇,是天一觀的道長。 經(jīng)常有香客問我蔚携,道長希太,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任酝蜒,我火速辦了婚禮誊辉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秕硝。我一直安慰自己芥映,他們只是感情好洲尊,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布远豺。 她就那樣靜靜地躺著,像睡著了一般坞嘀。 火紅的嫁衣襯著肌膚如雪躯护。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天丽涩,我揣著相機與錄音棺滞,去河邊找鬼。 笑死矢渊,一個胖子當(dāng)著我的面吹牛继准,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播特愿,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼捐川,長吁一口氣:“原來是場噩夢啊……” “哼掖蛤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起崔泵,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤秒赤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后憎瘸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體入篮,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年幌甘,在試婚紗的時候發(fā)現(xiàn)自己被綠了潮售。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡锅风,死狀恐怖饲做,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情遏弱,我是刑警寧澤盆均,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站漱逸,受9級特大地震影響泪姨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饰抒,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一肮砾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧袋坑,春花似錦仗处、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至也颤,卻和暖如春洋幻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背翅娶。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工文留, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人竭沫。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓燥翅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜕提。 傳聞我的和親對象是個殘疾皇子森书,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

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