Python進階1 - 正則表達式: 一文掌握正則表達式編程

小馬哥正在為Python的所有常見知識進行匯總,更會有大量實戰項目
點擊--> 全棧工程師養成---Python內容導航頁 <--查看所有Python內容

導語

正則表達式本質是一種字符串模式或者叫字符串模板,用來匹配一些列的字符串,找到目標字符串的過程就是匹配或者搜索,找到這些目標字符串之后,就可以對其進行提取,進行拆分,進行替換等等. 這也就是正則表達式和編程語言的邏輯關系,正則表達式規定了如何定義模式,編程語言使用正則表達式確定的邏輯模式,進行功能實現(匹配,搜索,提取,查分,替換等功能).

主要內容:

  • (2)先使用Python的re模塊,實現正則表達式編程
  • (1)正則表達式基本知識點

我故意把順序倒過來,雖然先有正則再有Python對正則表達式的支持, 我們先把知識用起來,然后不用太多解釋,你已經清楚正則是用來干什么了.目的還是保證: 一篇文章精通正則表達式,以及Python使用正則表達式熟練編程.

(一)用Python針對正則表達式編程

先把"見豬跑",直觀認識正則表達式與Python利用正則表達式實現一定功能,介紹常用的函數或者方法

1.1 match()函數

作用: 匹配正則表達式,如果匹配成功就返回一個匹配對象;如果匹配失敗,就返回None. 匹配對象的group()方法用于顯示成功的匹配.

例1,實現最簡單的正則表達式,

import re
# 正則表達式模式
pattern = 'China'
# 字符串文本
data = 'China'
# 通過re模塊的的match方法,從data的起始部分開始,對正則表達式模式進行比對,如果匹配,返回一個匹配對象;否則返回None
result = re.match(pattern,data)
print(type(result))  # 返回 <class 're.Match'>
print(result.group()) # Match對象的group()會返回成功的匹配.

例2,最簡單的正則表達式模式,之如果匹配失敗是什么樣子的

import re

pattern = 'China'
datas= 'Chinese','Python','China is a great country'

for data in datas:
    result = re.match(pattern,data)
    if result is not None:
        print("匹配成功: ",result)
    else:
        print('匹配失敗: ',data)
匹配失敗:  Chinese
匹配失敗:  Python
匹配成功:  <re.Match object; span=(0, 5), match='China'>

上面的模式(或者認為是模板)中,pattern就是一個簡單的字符串,但是這樣的模式只能匹配一個單詞,如果想匹配更多的情況,模式應該怎么寫?

例3,能夠匹配一個范圍的字符

import re
pattern = '[abc]'   #使用[]括起來的內容,代表一個集合,代表匹配集合內的任意一個字符,[abc]代表可以匹配a或者b或者c
datas = 'a','b','c','e','xay'

for data in datas:
    result = re.match(pattern,data)
    if result is not None:
        print('Match Successfully: ',result.group())  # group()函數的作用: 返回Match對象匹配到的字符內容
    else:
        print('Match Failed: ',data)

例4,上面的例子中[abc]指代了一個集合,元素之間是或的關系,也可以把這個集合看做一個范圍,

還有一種表示方法[a-z][A-Z][0-9],也是指代范圍,[a-c]也是同樣的意思

import re
pattern = '[a-e]'   #[a-e]代表了a到e這個字符范圍內的任何一個字符
datas = 'a','b','c','e','xay'

for data in datas:
    result = re.match(pattern,data)
    if result is not None:
        print('Match Successfully: ',result.group())  # group()函數的作用: 返回Match對象匹配到的字符內容
    else:
        print('Match Failed: ',data)

例5,點號'.' 匹配任意的單個字符(換行符和非字符除外)

import re
pattern = '李.'
names='李逵','李鬼','小李'
for name in names:
    isMatched = re.match(pattern,name)
    if isMatched:
        print('Match Successfully: ',isMatched)
    else:
        print('Match Faied: ',name)
Match Successfully:  <re.Match object; span=(0, 2), match='李逵'>
Match Successfully:  <re.Match object; span=(0, 2), match='李鬼'>
Match Faied:  小李

1.2 search()函數

作用: 在字符串中查找指定的模式,返回第一次出現的位置

match()函數的作用是在目標字符串的起始位置開始匹配,是否符合正則表達式模式. 我們很多場景可能不一定在字符串起始位置,更多情況是在字符內搜索是否有匹配正則模式的字符串存在,這就是search()函數的存在意義了.

例1,在一段文本中查找目標字符串

import re
data = '我愛偉大的祖國,I love China,China is a great country'     #China在data字符串中的位置區間為[15,20)  半開半閉區間
pattern = 'China'
result = re.search(pattern,data)
print(result.group())

print(data[19])

China
a

例2,點號"."的使用,搜索除去換行符之外的任意字符

import re
sentence='華為是華人的驕傲'    #1,通過這個句子1可以體會點號的作用;2,search()函數會返回第一次匹配
pattern='華.'
result = re.search(pattern,sentence)   
if result:
    print(result.group())
華為

who laughs last laughs best

1.3 findall()和finditer()函數

作用:

  • findall()查詢字符串中某個正則表達式全部的非重復出現情況,返回的是一個列表.
  • finditer()返回的是一個迭代器,所以相比findall()更加節省內存
import re
sentence='華為是華人的驕傲'
pattern = '華.'
result = re.findall(pattern,sentence)
print(result)
['華為', '華人']
import re
sentence = '華為是華人的驕傲'
pattern = '華.'
result = re.finditer(pattern,sentence)
print(type(result))
<class 'callable_iterator'>

1.4 group()和groups()方法

作用: 匹配對象的兩個方法

  • 匹配對象: match()或者search()成功調用后返回的對象

  • 子組: 圓括號對匹配模式的各個部分進行分組和提取操作,子組可以帶來的方便是,不用通過match之后,再來對特定字符串進行抽取

  • group(): 返回整個匹配對象或者返回特定的子組

  • groups(): 返回一個包含唯一或者全部子組的元組

  • 如果沒有子組的要求,那么當group()仍然返回整個匹配時,groups()返回一個空元組.

例1,無子組的模式返回使用group()匹配對象

import re
pattern = 'a'
data = 'abcd'
result = re.match(pattern,data)
print(result)
print(result.group())
print(result.groups())
<re.Match object; span=(0, 1), match='a'>
a
()
import re
pattern = '(華.)\w(華.)'
sentence = '華為是華人的驕傲'
result = re.search(pattern,sentence)
print(result)
print(result.group())  #返回整個匹配對象
print(result.group(0)) #返回整個匹配對象
print(result.group(1)) #返回子組1
print(result.group(2)) #返回子組2
print(result.groups()) #返回包含所有子組的元組
<re.Match object; span=(0, 5), match='華為是華人'>
華為是華人
華為是華人
華為
華人
('華為', '華人')

1.5 compile()函數

作用: 編譯正則表達式

import re
pattern = '(華.)\w(華.)'
sentence = '華為是華人的驕傲'
compiled_pattern = re.compile(pattern)  #<class 're.Pattern'>
print(type(compiled_pattern))
# result = re.match(compiled_pattern,sentence)   #(-1-)這樣做,
result = re.match(pattern,sentence)       # (-2-)<class 're.Match'>
print(result)#(-1-)(-2-)得到的結果都是一樣的,但是在多次用到compiled_pattern的時候,會節省了編譯pattern的這個過程
<class 're.Pattern'>
<re.Match object; span=(0, 5), match='華為是華人'>

1.6 sub()和subn()函數

作用: 實現搜索和替換(找到目標字符串,然后替換掉)

sub()完成替換,返回一個被替換完成之后的字符串

subn()完成替換,還返回被替換的數量,字符串和數組,組成元組返回

import re
sentence = 'Java是很受歡迎的編程語言'
pattern = '[a-zA-Z]+'   # [字符集范圍]   " + "代表: 前面的模式出現1次以上

result = re.sub(pattern,'Python',sentence)  # 使用新的Python替代
print(result)
resultn = re.subn(pattern,'Python',sentence)
print(resultn)
Python是很受歡迎的編程語言
('Python是很受歡迎的編程語言', 1)
import re
sentence = 'Java是一門強大的語言,Go前途不錯'
pattern = 'Java|Go'  # 或關系
result = re.sub(pattern,'Python',sentence)
print(result)
Python是一門強大的語言,Python前途不錯

1.7 split()

作用: 實現分隔字符串

import re
data = '百度,騰訊,阿里,華為,智能天下'
pattern = ','
result = re.split(pattern,data)
print(type(result))
print(result)
<class 'list'>
['百度', '騰訊', '阿里', '華為', '智能天下']

(二) 正則表達式的知識點匯總

介紹正則的知識點,用于編輯正則表達式,

2.1 正則模式中的字符

  • 最簡單的,任意一個字符串都是一個正則表達式的模式(但是這樣的通用性不強,只能匹配一個特定字符串,沒有什么意義)

  • 匹配一定范圍內的單個字符1[abc]: 中括號里面的內容即"或"的關系

  • 匹配一定范圍內的單個字符2[a-c]: 使用連接符,代表范圍,[a-z][0-9]

  • 代表單個字符的特殊符號:

    1. "."點號: 匹配任意字符(字母,數字,特殊字符,但是換行符除外)

    2. \w: 匹配任意字母,數字(比上面的"."少了特殊字符)

    3. \d: 匹配任意十進制數字(比上面的\w少了字母)

    4. \s: 匹配空白

    5. \b: 匹配邊界

    6. ^: 匹配開始

    7. $: 匹配結尾

    8. 注意: 如果要在模式中匹配上面出現的特殊字符,例如: ".","","^","$",需要使用轉義字符:\

2.2 正則中頻數的表示

概括的表示頻數

  • *: 代表匹配0次或者多次
  • +: 代表匹配1次或者多次
  • ?: 代表匹配0次或者一次

精確的表示頻數

  • {n}: 代表前面的模式出現n次
  • {m,n}: 代表前面的模式出現m到n次之間

2.3 其它重要知識點

分組

模式中被"()"括起來的內容,是可以被提取的,Python以及各種語言實現了這種功能,group()

模式的邏輯或與否定

  1. "|" 代表兩個模式的或關系

    例如: bat|tmd 可以匹配:bt,bm,bd,at,am,ad,tt,tm,td

    同: [bat][tmd]

  2. "^" 除匹配字符串的開始之外,如果用在[]中,代表否定的意思

    例如: [\d]代表的是一個十進制數,[^\d]代表除十進制數之外的其它模式

正則表達式的擴展表示法

2.4 轉義字符與原始字符串

轉義字符: \ 在字符串中,轉義字符用于輸出一些特殊字符,例如:\b,代表的是退格,\n代表換行,\t代表制表符,本質上,字符串的轉義字符,是為了打印準備的,所以我們暫且定義: 字面量和打印量

原始字符串: 把字母"r"放在字符串開頭,代表這是一個原始字符串,它的作用在于消除字符串和正則表達式之間各自關于轉義的歧義,例如: \b在正則中表示邊界

在cmd窗口里面,定義一個字符串data = '\',輸入data與print(data)得到的是不一樣的結果,前者是'\',后者是'',這就是字面量和打印量的區別

這個時候再來解釋轉義在字符串中和正則中的歧義問題就明了了

data = 'ab\cd' # 現在需要要匹配出data中的\怎么處理

首先,data的字面量,也就是字符串的真實值看似是'ab\cd',其實,你用cmd窗口,直接輸出data而不是print(data),會發現,字符串的字面顯示: ab\cd
所以要匹配出來data的'',pattern要如何寫呢?

pattern1 = ''

pattern2 = '\'

pattern3 = '\\'

結果是第三個,首先pattern是一個字符串,雖然要交給正則表達式引擎去解析,但是終歸是一個字符串,那么就要經過字符串的轉義處理,第一個語法錯誤,這個''首先轉義了結尾的"'",字符串沒有結尾了;第二個,'\'是正確的字符串,經過字符串轉義后,字面量是\,傳遞給正則引擎的時候和打印的時候一樣,是'',但是真實的data字面量是'\',肯定匹配不到,于是只能用第三種

小馬哥正在為Python的所有常見知識進行匯總, 更會有大量實戰項目
點擊--> 全棧工程師養成---Python內容導航頁 <--查看所有Python內容

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容

  • Python中的正則表達式(re) import rere.match #從開始位置開始匹配,如果開頭沒有則無re...
    BigJeffWang閱讀 7,118評論 0 99
  • `>本文是 Jan Goyvaerts 為 RegexBuddy 寫的教程的譯文,版權歸原作者所有 在本文中講述了...
    極客圈閱讀 2,093評論 0 5
  • #首先,python中的正則表達式大致分為以下幾部分: 元字符 模式 函數 re 內置對象用法 分組用法 環視用法...
    mapuboy閱讀 1,626評論 0 51
  • re模塊手冊 本模塊提供了和Perl里的正則表達式類似的功能,不關是正則表達式本身還是被搜索的字符串,都可以...
    喜歡吃栗子閱讀 4,028評論 0 13
  • 搞懂Python 正則表達式用法 Python 正則表達式 正則表達式是一個特殊的字符序列,它能幫助你方便的檢查一...
    廈熱閱讀 1,598評論 0 2