Python正則表達(dá)式(一)

前言

正則表達(dá)式(Regular Expression)妖爷,就是具有一定規(guī)則的表達(dá)式班利。通過(guò)正則表達(dá)式引擎歼秽,將這些規(guī)則轉(zhuǎn)換為正則表達(dá)式對(duì)象折砸,然后再去文本中搜索能夠與之匹配的字符串莲组。

正則表達(dá)式的語(yǔ)法都是一樣的诊胞,只是不同編程語(yǔ)言的實(shí)現(xiàn)不同,大部分都是師從Perl锹杈。

對(duì)Perl語(yǔ)言有所了解的朋友撵孤,學(xué)習(xí)python正則應(yīng)該是手到擒來(lái)。

正則表達(dá)式入門

Python中的re模塊提供了強(qiáng)大的正則表達(dá)式功能竭望。

而第三方模塊regex提供了與標(biāo)準(zhǔn)庫(kù)re模塊兼容的API接口, 同時(shí)還提供了額外的功能和更全面的Unicode支持早直。

匹配字符

大多數(shù)字母和字符只會(huì)匹配自身,例如:python只會(huì)匹配自己市框,不會(huì)匹配Python霞扬。

但是有一些字符串,它們不表示自身,而是具有一些特殊含義喻圃,只能通過(guò)\轉(zhuǎn)義之后才表示自身萤彩。

這些字符包括:

. ^ $ * + ? { } [ ] \ | ( )

.:

  • 在默認(rèn)模式中,匹配除換行外所有字符斧拍,如果指定了DOTALL標(biāo)簽雀扶,則表示任意字符
import re

"""
re.findall(pattern, string, flags=0)
pattern: 匹配規(guī)則,字符串
string: 需要去匹配的字符串

從左到右進(jìn)行掃描肆汹,匹配按找到的順序返回愚墓。如果樣式里存在一個(gè)或多個(gè)組,就返回一個(gè)組合列表
"""

re.findall('ab.', 'abc') 
# Out[1]: ['abc']

re.findall('ab.', 'ab\n') 
# Out[2]: []

re.findall('ab.', 'ab\n', re.DOTALL)
# Out[3]: ['ab\n']

^:

  • 匹配字符串的開(kāi)頭昂勉, 如果是MULTILINE模式浪册,匹配每行開(kāi)頭(\n之后)的首個(gè)符號(hào)。
  • 在字符集中可表示'非'岗照,[^a]表示除字符a之外的字符村象。
re.findall('^ab', 'abcda\nabddd')                                     
# Out[4]: ['ab']

re.findall('^ab', 'abcda\nabddd', re.MULTILINE)
# Out[5]: ['ab', 'ab']

re.findall('[^a]', 'aaa\nbbb')
# Out[6]: ['\n', 'b', 'b', 'b']

$:

  • 匹配字符串的末尾,或者在字符串末尾換行符的前一個(gè)字符攒至。
  • MULTILINE 模式下匹配每行末尾(\n之前)的字符厚者。
re.findall('ab$', 'abcdab\nabdab')                                   
# Out[7]: ['ab']

# 上面結(jié)果中的 ab 是 \n 前面的還是后面的呢?進(jìn)行如下測(cè)試迫吐,發(fā)現(xiàn)是后面的 ab 被匹配了
re.findall('ab.$', 'abcdab1\nabdab2')
# Out[8]: ['ab2']

# 在 MULTILINE 模式下库菲,兩個(gè)都被匹配了
re.findall('ab$', 'abcdab\nabdab', re.MULTILINE)
# Out[9]: ['ab', 'ab']

# 而對(duì) $ 在換行結(jié)尾的字符串中匹配時(shí),會(huì)得到兩個(gè)空字符志膀,一個(gè)在換行符之前蝙昙,一個(gè)在字符串的末尾
re.findall('$', 'abcdab1\n')
# Out[10]: ['', '']

*:

  • 匹配前一個(gè)規(guī)則0次或無(wú)限次
re.findall('ab*', 'a')
# Out[11]: ['a']

re.findall('ab*', 'ab')
# Out[12] ['ab']

re.findall('ab*', 'abbbbbbbbbbbbbb')
# Out[13] ['abbbbbbbbbbbbbb']

+:

  • 匹配前一個(gè)規(guī)則1次或無(wú)限次
re.findall('ab+', 'a')
# Out[14]: []

re.findall('ab+', 'ab')
# Out[15] ['ab']

re.findall('ab+', 'abbbbbbbbbbbbbb')
# Out[16] ['abbbbbbbbbbbbbb']

?:

  • 匹配前一個(gè)規(guī)則0次或1次
re.findall('ab?', 'a')
# Out[17]: ['a']

re.findall('ab?', 'ab')
# Out[18] ['ab']

re.findall('ab?', 'abbbbbbbbbbbbbb')
# Out[19] ['ab']

.?,*?,??:

  • .,*,?修飾符都是貪婪的,會(huì)盡可能的匹配更多的字符串
  • 貪婪的我梧却,當(dāng)然是贊越多越好呀。
  • 而在這些修飾符后面加上?败去,便成了非貪婪模式放航,會(huì)盡可能少的匹配字符串
re.findall('<.*>', '<a>bcd>')
# Out[20] ['<a>bcd>']

re.findall('<.*?>', '<a>bcd>')
# Out[21] ['<a>']

{m}:

  • 指定前面的正則表達(dá)式出現(xiàn)的次數(shù),出現(xiàn)次數(shù)必須完全一致圆裕。
re.findall('a{3}', 'aa') 
# Out[22]: []

re.findall('a{3}', 'aaaaa')
# Out[23]: ['aaa']

{m, n}:

  • 指定前面的正則表達(dá)式出現(xiàn)的次數(shù)在m~n之間广鳍,盡可能多的匹配,匹配的下界是m吓妆,上界是n赊时。
  • 若缺省m,下界為0行拢,若缺省n祖秒,為不設(shè)上界,即無(wú)限次。
re.findall('a{3, 5}', 'aaaa') 
# Out[24]: []

# 3,5 之間不能添加空格
re.findall('a{3,5}', 'aaaa')
# Out[25]: ['aaaa']

re.findall('a{3,}', 'aaaa')
# Out[26]: ['aaaa']

re.findall('a{,5}', 'aaaa')
# Out[27] ['aaaa', '']

{m, n}?:

  • 即非貪婪模式竭缝,盡可能少的匹配字符串房维。
re.findall('a{3,}?', 'aaaaa')
# Out[28] ['aaa']

\:

  • 轉(zhuǎn)義特殊字符。如'\.'只表示.抬纸,而不再是表示任意字符咙俩。
  • 匹配\字符需要轉(zhuǎn)義,用\\表示
re.findall('\.', 'aa')
# Out[29] []

re.findall('\.', 'aa.')
# Out[30] ['.']
  • 反斜杠災(zāi)難:反斜杠具有轉(zhuǎn)義作用湿故,如果需要匹配的字符串中存在多個(gè)\阿趁,就需要調(diào)加相應(yīng)數(shù)量的\來(lái)轉(zhuǎn)義
re.findall('\\\\ab', '\\abc') # ['\\ab']
"""
在反復(fù)使用反斜杠的正則中,這會(huì)導(dǎo)致大量重復(fù)的反斜杠坛猪,
并使得生成的字符串難以理解脖阵。
解決方案:
  使用 Python 的原始字符串表示法來(lái)表示正則表達(dá)式;
  'r' 為前綴的字符串砚哆,反斜杠不再表示轉(zhuǎn)義
"""
re.findall(r'\\ab', '\\abc')  # ['\\ab']

re.findall(r'\n', '\n')       # ['\n']

[ ]:

  • 表示字符集集合独撇。匹配該字符需要轉(zhuǎn)義\[,\]
# 1、單獨(dú)列出躁锁,匹配 a纷铣、b 或 c
re.findall('[abc]', 'ab.')
# Out[31]: ['a', 'b']

"""
2、字符范圍:
[a-j]: 表示小寫(xiě)字母 a~j
[1-6]:表示數(shù)字 1~6
轉(zhuǎn)義: 如 [a\-z] 或者它的位置在首位或者末尾([-a] 或 [a-])战转,它就只表示普通字符 '-'搜立。
""" 
re.findall('[a\-z]', '-')
# Out[32]: ['-']

re.findall('[-a]', '-')
# Out[33]: ['-']

re.findall('[a-]', '-')
# Out[34]: ['-']

"""
3、特殊字符失去特殊含義
  比如 [(+*)] 只會(huì)匹配這幾個(gè)字符 '(', '+', '*', or ')'槐秧。
"""
re.findall('[(+*)]', '+-*/()')
# Out[35] ['+', '*', '(', ')']

"""
4啄踊、字符類
 可以使用字符類:\w,\S 等刁标,它們可以匹配的字符由 ASCII 或者 LOCALE 模式?jīng)Q定颠通。
"""
re.findall('[\w]', 'abfagg-/*-')
# Out[36] ['a', 'b', 'f', 'a', 'g', 'g']

"""
5、取反
如果集合首字符是 '^' 膀懈,所有不在集合內(nèi)的字符將會(huì)被匹配
[^^] 將匹配所有字符顿锰,除了 '^'. 
^ 如果不在集合首位,就沒(méi)有特殊含義启搂。
"""
# 非 \w 定義的字母
re.findall('[^\w]', 'abfagg-/*-')
# Out[37] ['-', '/', '*', '-']

"""
6硼控、匹配字符 ']'
兩種方法
  加上反斜杠
  放到集合首位
"""
# 加上反斜杠
re.findall('\]', 'abc]')
# Out[38] [']']

# 放到集合首位
re.findall('[]{}]', ']abc')
# Out[39] [']']

|:

  • 或。A|B胳赌,匹配正則表達(dá)式AB牢撼,AB可以是任何正則表達(dá)式疑苫。
  • 如果A匹配成功熏版,則不會(huì)再匹配B纷责。
  • 匹配|字符需要轉(zhuǎn)義,\|[|]
re.findall('a|b', 'acb')
# Out[40] ['a', 'b']

re.findall('[|]', 'ab|c')
# Out[41] ['|']

(...):

  • 小括號(hào)纳决,可以組合表達(dá)式碰逸,匹配括號(hào)內(nèi)的組合表達(dá)式,并標(biāo)注表達(dá)式的開(kāi)始和結(jié)束位置阔加,可用于后續(xù)捕獲
  • 每對(duì)小括號(hào)代表一個(gè)組合饵史,可以通過(guò)\number的方式引用組合,\1表示第一個(gè)組合胜榔。
  • 要匹配字符 ( 或者 ), 用 \(\), 或者放在字符集合里: [(], [)]胳喷。
re.findall('a(b+)', 'abbb')
# Out[42] ['bbb']
。
re.findall(r'(b)a\1', 'bab')
# Out[43] ['b']

總結(jié)

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夭织,一起剝皮案震驚了整個(gè)濱河市吭露,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尊惰,老刑警劉巖讲竿,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異弄屡,居然都是意外死亡题禀,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門膀捷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)迈嘹,“玉大人,你說(shuō)我怎么就攤上這事全庸⌒阒伲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵壶笼,是天一觀的道長(zhǎng)神僵。 經(jīng)常有香客問(wèn)我,道長(zhǎng)覆劈,這世上最難降的妖魔是什么保礼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮墩崩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侯勉。我一直安慰自己鹦筹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布址貌。 她就那樣靜靜地躺著铐拐,像睡著了一般徘键。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遍蟋,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天吹害,我揣著相機(jī)與錄音,去河邊找鬼虚青。 笑死它呀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棒厘。 我是一名探鬼主播纵穿,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼奢人!你這毒婦竟也來(lái)了谓媒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤何乎,失蹤者是張志新(化名)和其女友劉穎句惯,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體支救,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抢野,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搂妻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒙保。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖欲主,靈堂內(nèi)的尸體忽然破棺而出邓厕,到底是詐尸還是另有隱情,我是刑警寧澤扁瓢,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布详恼,位于F島的核電站,受9級(jí)特大地震影響引几,放射性物質(zhì)發(fā)生泄漏昧互。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一伟桅、第九天 我趴在偏房一處隱蔽的房頂上張望敞掘。 院中可真熱鬧,春花似錦楣铁、人聲如沸玖雁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赫冬。三九已至浓镜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間劲厌,已是汗流浹背膛薛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留补鼻,地道東北人哄啄。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像辽幌,于是被迫代替她去往敵國(guó)和親增淹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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