Python正則表達(dá)式

方法歸納

方法 描述
findall 將字符串中所有的非重疊匹配模式以列表形式返回
finditer 與findall類似,但返回的是迭代器
match 在字符串起始位置匹配模式,也可以將模式組件匹配到分組中;
如果模式匹配上了,返回一個(gè)匹配對(duì)象,否則返回None
search 掃描字符串的匹配模式,如果掃面到了返回匹配對(duì)象;
與match方法不同的是,search方法的匹配可以是字符串的任意位置,
而不僅僅是字符串的起始位置
split 根據(jù)模式,將字符串拆分為多個(gè)部分
sub,subn 用替換表達(dá)式替換字符串中所有的匹配(sub)或第n個(gè)出現(xiàn)的匹配串(subn);
使用符號(hào)\1,\2....來引用替換字符串中匹配組的元素

compile

正則表達(dá)式提供了一種在文本中靈活查找或匹配字符串模式的方法。單個(gè)表達(dá)式通常被稱為regex,是根據(jù)正則表達(dá)式語(yǔ)言形成的字符串。Python內(nèi)建的re模塊是用于將正則表達(dá)式應(yīng)用到字符串上的庫(kù)。接下來展示一些re模塊的實(shí)例。

re模塊主要有三個(gè)主題:模式匹配、替代、拆分。當(dāng)然,這三個(gè)主題是相關(guān)聯(lián)的。一個(gè)正則表達(dá)式描述了在文本中需要定位的一種模式,可以用于多種目標(biāo)。
讓我們來看一個(gè)簡(jiǎn)單的示例:假設(shè)我們想將含有多種空白字符(制表符、空格、換行符)的字符串拆分開。描述一個(gè)或多個(gè)空白字符的正則表達(dá)式是\s+:

import re
text = "foo      bar\t baz    \tqux"
re.split('\s+', text)

當(dāng)調(diào)用re.split('\s+', text)時(shí),正則表達(dá)式首先會(huì)被編譯,然后正則表達(dá)式的split方法在傳入文本上被調(diào)用。也可以使用re.compile自行編譯,形成一個(gè)可復(fù)用的正則表達(dá)式對(duì)象。

regex = re.compile('\s+')
regex.split(text)

以上兩段執(zhí)行結(jié)果相同:

['foo', 'bar', 'baz', 'qux']

findall

如果需要獲得的是一個(gè)所有匹配正則表達(dá)式的模式的列表,你可以使用findall方法:

regex.findall(text)

//out: ['      ', '\t ', '    \t']

PS:為了在正則表達(dá)式中避免轉(zhuǎn)義符\的影響,可以使用原生字符串語(yǔ)法,比如 r'C:\x' 或者用等價(jià)的 'C:\x'
如果需要將相同的表達(dá)式應(yīng)用在多個(gè)字符串上,推薦使用re.compile創(chuàng)建一個(gè)正則表達(dá)式對(duì)象,這樣做有利于節(jié)約CPU周期。

search、match

match和search與findall相關(guān)性很大。findall返回的是字符串中所有的匹配項(xiàng),而search返回的僅僅是第一個(gè)匹配項(xiàng)。match更為嚴(yán)格,它只在字符串的起始位置進(jìn)行匹配。我們來看下一個(gè)示例,一段文本和一個(gè)可以識(shí)別大部分電子郵件地址的正則表達(dá)式:
在文本上使用findall會(huì)生成一個(gè)電子郵件地址的列表:

text = '''Dava dava@google.com
    Steve steve@gmail.com
    Rob rob@gmail.com
    Ryan ryan@yahoo.com
'''
pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
# re.IGNORECASE 使正則表達(dá)式不區(qū)分大小寫
regex = re.compile(pattern, flags=re.IGNORECASE)
regex.findall(text)

//out: ['dava@google.com', 'steve@gmail.com', 'rob@gmail.com', 'ryan@yahoo.com']

search返回的是文本中第一個(gè)匹配到的電子郵件地址。對(duì)于前面提到的正則表達(dá)式,匹配對(duì)象只能告訴我們模式在字符串中起始和結(jié)束的位置:

m = regex.search(text)
m

//out: <re.Match object; span=(5, 20), match='dava@google.com'>
text[m.start():m.end()]

//out: 'dava@google.com'

regex.match只在模式出現(xiàn)于字符串起始位置時(shí)進(jìn)行匹配,如果沒有匹配到,返回None:

print(regex.match(text))
//out: None

sub

sub會(huì)返回一個(gè)新的字符串,原字符串中的模式會(huì)被一個(gè)新的字符串替代:

s = regex.sub('REDACTED',text)
print(s)

//out: Dava REDACTED
        Steve REDACTED
        Rob REDACTED
        Ryan REDACTED

擴(kuò)展

假設(shè)想查找電子郵件地址,并將每個(gè)地址分為三個(gè)部分:用戶名、域名和域名后綴。要實(shí)現(xiàn)這一點(diǎn),可以用括號(hào)將模式包起來。由下面修改后的正則表達(dá)式產(chǎn)生的匹配對(duì)象的groups方法,返回的是模式組件的元組:

pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex = re.compile(pattern, flags = re.IGNORECASE)
m = regex.match('wesm@bright.net')
m.groups()

//out: ('wesm', 'bright', 'net')

當(dāng)模式可以分組時(shí),findall返回的是包含元組的列表:

regex.findall(text)

//out: [('dava', 'google', 'com'),
 ('steve', 'gmail', 'com'),
 ('rob', 'gmail', 'com'),
 ('ryan', 'yahoo', 'com')]

sub也可以使用特殊符號(hào),如\1和\2,訪問每個(gè)匹配對(duì)象中的分組。符號(hào)\1代表的是第一個(gè)匹配分組,\2代表的是第二個(gè)匹配分組,以此類推:

L = regex.sub(r'Username: \1, Domain: \2, Suffix: \3', text)
print(L)

//out: Dava Username: dava, Domain: google, Suffix: com
    Steve Username: steve, Domain: gmail, Suffix: com
    Rob Username: rob, Domain: gmail, Suffix: com
    Ryan Username: ryan, Domain: yahoo, Suffix: com

去掉\3,便于理解

L = regex.sub(r'Username: \1, Domain: \2, Suffix: ', text)
print(L)

//out:Dava Username: dava, Domain: google, Suffix: 
    Steve Username: steve, Domain: gmail, Suffix: 
    Rob Username: rob, Domain: gmail, Suffix: 
    Ryan Username: ryan, Domain: yahoo, Suffix: 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容