Python操作正則表達式

什么是正則表達式?

正則表達式(Regular Expression)留拾,又稱規(guī)則表達式涕侈,通常被用來檢索、替換那些符合某個模式(規(guī)則)的文本秒旋。許多程序設(shè)計語言都支持利用正則表達式進行字符串操作约计。

Python 自1.5版本起增加了re 模塊,它提供 Perl 風(fēng)格的正則表達式模式迁筛。re 模塊使 Python 語言擁有全部的正則表達式功能煤蚌。

正則表達式的使用對特殊字符進行了轉(zhuǎn)義,所以如果我們要使用原始字符串,只需加一個 r 前綴尉桩。

元字符

正則表達式由一些普通字符和一些元字符(metacharacters)組成筒占。普通字符包括大小寫的字母和數(shù)字,而元字符則具有特殊的含義蜘犁。下列為一些常見的元字符的使用說明翰苫。

匹配邊界:
    ^     匹配行首
    $     匹配行尾
    
重復(fù)次數(shù):
    ?    重復(fù)匹配0次或1次
    *     重復(fù)匹配0次或更多次
    +     重復(fù)匹配1次或更多次
    {n}   重復(fù)n次
    {n,}  重復(fù)n次或更多次
    {n,m} 重復(fù)n~m次
    
各種字符的表示:
    .     匹配除了換行符以外的任意字符串
    [a-z] 任意a-z的字母
    [abc] a,b,c中任意字符
    \d    匹配數(shù)字
    \D    匹配任意非數(shù)字的字符
    \w    數(shù)字这橙,字母奏窑,下劃線
    \W    匹配任意不是字母,數(shù)字屈扎,下劃線的字符
    \s    空白字符(回車埃唯,制表,空格)
    \S    匹配任意不是空白符的字符
    \b    單詞的邊界
    \B    匹配不是單詞開始和結(jié)束的位置
    
其他:
    [^123abc] 匹配除了123abc這幾個字符以外的任意字符
    123|abc   匹配123或者abc 

Pattern 對象

compile 函數(shù)用于編譯正則表達式助隧,生成一個正則表達式( Pattern )對象筑凫,供 re 模塊的查找方法使用。語法格式為:

pattern = re.compile(r'正則表達式'并村,'匹配模式')

# 常用的匹配模式:
#   re.S    可以讓 . 匹配換行符
#   re.I    忽略大小寫
#   re.M    多行匹配巍实,影響 ^ 和 $ 

單次匹配

re 模塊中,有兩個方法哩牍,match 函數(shù)和 search 函數(shù)棚潦,這兩個函數(shù)都是單次匹配,都返回一個
Match 對象膝昆。

re.match(pattern, string, start, end)
# pattern.match(string, start, end)

re.search(pattern, string, start, end)
# pattern.match(string, start, end)

# pattern  正則表達式對象
# string   要匹配的目標(biāo)字符串
# start    要匹配的目標(biāo)字符串的起始位置(可選)
# end為    要匹配的目標(biāo)字符串的結(jié)束位置(可選)

"""案例"""

import re

pattern = re.compile(r'\w+', re.I)

string = 'I love python'

result = pattern.match(string, 2, 6)

print(result)
# <re.Match object; span=(2, 6), match='love'>

print(result.group())
# love

需要注意的是丸边,match 函數(shù) 只匹配字符串的開始,如果字符串開始不符合正則表達式荚孵,則匹配失敗妹窖,函數(shù)返回 None,而 search 函數(shù)是匹配整個字符串收叶,直到找到一個匹配骄呼。

import re

string = 'i am 18 !!!'

result1 = re.match(r'\d+', string)
result2 = re.search(r'\d+', string)

print(result1)
# None
print(result2.group())
# 18

分組

在Python中,正則表達式分組就是用一對圓括號“()”括起來的正則表達式判没,匹配出的內(nèi)容就表示一個分組蜓萄。即每個圓括號都是一個分組,從1開始澄峰。需要注意的是嫉沽,有一個隱含的全局分組(就是0),也就是整個正則表達式俏竞。

import re

pattern = re.compile(r'name is (.*),age:(\d+)', re.I)

string = 'my name is 啊哈哈君,age:18 !'

result = pattern.search(string)

print(result)
# <re.Match object; span=(3, 22), match='name is 啊哈哈君,age:18'>
print(result.group())
# name is 啊哈哈君,age:18
print(result.group(1))
# 啊哈哈君
print(result.group(2))
# 18

Match 對象

關(guān)于match函數(shù)和search函數(shù)返回的match對象绸硕,也是有很多方法可以調(diào)用的堂竟。如上述案例的group函數(shù),會返回被匹配的字符串臣咖。

# 返回被匹配的字符串跃捣,等價于group(0)
Match.group()  

# 返回第n個分組匹配的字符串,如果組號不存在夺蛇,則返回indexError異常
Match.group(n)

# 返回組號為n到m組所匹配的字符串的元組疚漆,如果組號不存在,則返回indexError異常
Match.group(n,m) 

# 返回所有分組匹配的字符串的元組
Match.groups()

# 返回匹配開始的位置
Match.start()

# 返回匹配結(jié)束的位置
Match.end()

# 返回一個元組包含匹配 (開始,結(jié)束) 的位置
Match.span()

多次匹配

re 模塊中的findall函數(shù)與finditer函數(shù)用于進行多次匹配刁赦。相信通過函數(shù)名娶聘,有些小伙伴就可以知道這兩個函數(shù)的返回值。

import re

string = 'abcdefg'

result1 = re.findall(r'\w', string)
result2 = re.finditer(r'\w', string)

print(result1)
# ['a', 'b', 'c', 'd', 'e', 'f', 'g']
print(result2)
# <callable_iterator object at 0x000002452F017848>

由上述案例可看出甚脉,多次匹配與單次匹配的函數(shù)用法相同丸升,也可以加start和end。只是findall函數(shù)返回的是一個列表牺氨,而finditer返回的是一個迭代器狡耻。

分割字符串

re 模塊提供了一個spilt函數(shù),用于通過正則表達式分割字符串猴凹,并返回一個列表夷狰。

import re

pattern = re.compile(r'\s', re.I)

string = 'python java c++'

result = pattern.split(string)

print(result)
# ['python', 'java', 'c++']

替換字符串

re 模塊中的sub函數(shù)用于通過正則表達式替換字符串。格式為:

re.sub(pattern, repl, string, count)
# pattern.sub(repl, string, count)

# pattern  正則表達式或者正則對象
# repl     替換的字符串郊霎,也可為一個函數(shù)
# string   要被查找替換的原始字符串
# count    匹配后替換的最大次數(shù)沼头,默認為0,表示替換所有的匹配

這個函數(shù)通過案例是很容易理解的书劝。

import re

pattern = re.compile(r'python', re.I)

string = 'I Love Python, Python NB!'

result1 = pattern.sub('java', string)
result2 = pattern.sub('java', string, 1)

print(result1)
# I Love java, java NB!
print(result2)
# I Love java, Python NB!

當(dāng)repl為函數(shù)時进倍,函數(shù)的參數(shù)只能為match對象,并且這個函數(shù)必須有返回值购对,返回值的格式是字符串猾昆,將來就用這個字符串作為替換的內(nèi)容。

import re

pattern = re.compile(r'python', re.I)


def func(matched):
    return matched.group()+' And Java'


string = 'I Love Python'

result = pattern.sub(func, string)

print(result)
# I Love Python And Java

貪婪模式與非貪婪模式

貪婪匹配:正則表達式一般趨向于最大長度匹配骡苞,也就是所謂的貪婪匹配毡庆。

非貪婪匹配:就是匹配到結(jié)果就好,取最少的匹配字符烙如。

在Python中,默認是貪婪模式毅否,而在正則表達式的量詞后面直接加上一個問號亚铁?就會轉(zhuǎn)換為非貪婪模式。

import re

string = 'i am 18 螟加!'

result1 = re.search(r'\d+', string)
result2 = re.search(r'\d+?', string)

print(result1.group())
# 18
print(result2.group())
# 1

在上述案例中的正則為\d+徘溢,也就是匹配數(shù)字1次或多次吞琐。也就是說,在貪婪模式下然爆,這個正則會往多的次數(shù)匹配站粟,也就是優(yōu)先多次,即匹配到了18曾雕,而非貪婪模式下奴烙,則會優(yōu)先匹配1次,也就是優(yōu)先匹配到了1剖张,滿足條件便會立刻返回結(jié)果切诀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搔弄,隨后出現(xiàn)的幾起案子幅虑,更是在濱河造成了極大的恐慌,老刑警劉巖顾犹,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件倒庵,死亡現(xiàn)場離奇詭異,居然都是意外死亡炫刷,警方通過查閱死者的電腦和手機擎宝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柬唯,“玉大人认臊,你說我怎么就攤上這事〕荩” “怎么了失晴?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拘央。 經(jīng)常有香客問我涂屁,道長,這世上最難降的妖魔是什么灰伟? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任拆又,我火速辦了婚禮,結(jié)果婚禮上栏账,老公的妹妹穿的比我還像新娘帖族。我一直安慰自己,他們只是感情好挡爵,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布竖般。 她就那樣靜靜地躺著,像睡著了一般茶鹃。 火紅的嫁衣襯著肌膚如雪涣雕。 梳的紋絲不亂的頭發(fā)上艰亮,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機與錄音挣郭,去河邊找鬼迄埃。 笑死,一個胖子當(dāng)著我的面吹牛兑障,可吹牛的內(nèi)容都是我干的侄非。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼旺垒,長吁一口氣:“原來是場噩夢啊……” “哼彩库!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起先蒋,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤骇钦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后竞漾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眯搭,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年业岁,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳞仙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡笔时,死狀恐怖棍好,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情允耿,我是刑警寧澤借笙,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站较锡,受9級特大地震影響业稼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蚂蕴,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一低散、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骡楼,春花似錦熔号、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春祠乃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背兑燥。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工亮瓷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人降瞳。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓嘱支,卻偏偏與公主長得像,于是被迫代替她去往敵國和親挣饥。 傳聞我的和親對象是個殘疾皇子除师,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348