5分鐘完全掌握正則表達(dá)式

前言
如果說(shuō)什么是我學(xué)習(xí)編程來(lái)最好用,最常用的知識(shí)點(diǎn),那應(yīng)該就是正則表達(dá)式了。嚴(yán)謹(jǐn)?shù)恼f(shuō),正則表達(dá)式并不是一門(mén)編程語(yǔ)言,也不是為了一種編程語(yǔ)言而服務(wù)的知識(shí)。但他確實(shí)足夠好用,應(yīng)用也足夠廣泛。
例如可以在文本中提取規(guī)則的電話(huà)號(hào)碼,電子郵箱。在office中的通配符也是正則表達(dá)式哦,這樣在office中做規(guī)則的搜索和替換,也是能極高的提升工作效率。

正則表達(dá)式在爬蟲(chóng)中也經(jīng)常使用到,例如只需要簡(jiǎn)單的幾行代碼,就可以獲取h1標(biāo)簽下的所有內(nèi)容。
import?re
html?=?'''
?test1?
?test2?
?test3?
'''
content?=?re.findall('(.*?)
',?html)
print(content)
#result?['?test1?',?'?test2?',?'?test3?']
那正則表達(dá)式到底是什么,又該如何使用,為什么我們爬蟲(chóng)中老是使用(.*?),它到底起到了什么作用,這篇文章就詳細(xì)告訴你。
什么是正則表達(dá)式
正則表達(dá)式(regular expression)描述了一種字符串匹配的模式(pattern),聽(tīng)起來(lái)確實(shí)不是很好理解。
我們從這個(gè)定義中抽出三個(gè)關(guān)鍵詞:
字符串:這個(gè)定義了使用的對(duì)象,也就是文本。 匹配:定義了用途,用于查找定位。 模式:模式其實(shí)就是規(guī)則,這就是正則表達(dá)式的核心,這里的規(guī)則是人為定義好的,可以是字符,數(shù)字和字母。
所以用大白話(huà)來(lái)說(shuō),正則表達(dá)式就是一些人為定義的規(guī)則,進(jìn)行組合,使其具有快速匹配字符串的功能。
元字符
前面說(shuō)到正則表達(dá)式就是一些定義好的規(guī)則的組合,這個(gè)規(guī)則背后就是元字符。
元字符有很多,我們按用途將他們分為5類(lèi),便于理解和使用。
集合:[ ] 次數(shù):表示次數(shù):* + ? {} 并列:| 提?。?) 特定意義符號(hào):. ^ $ \b\B
本篇文章的實(shí)例都在該網(wǎng)站上在線驗(yàn)證:https://regex101.com/ (1)集合([ ]) [ ]表示匹配所包含的任意一個(gè)字符,例如[Pp]ython,就能匹配Python和python。

在集合中使用-,可以匹配一個(gè)范圍內(nèi)的字符,例如[a-z]可以匹配a到z任意一個(gè)字符。

使用 ^ 可以匹配補(bǔ)集,例如[^p]ython,就能匹配除了p之外的字符。

(2)次數(shù)字符 上面的正則表達(dá)式只能匹配一個(gè)字符,這時(shí)你就需要次數(shù)相關(guān)的字符。
* 表示后面可跟 0 個(gè)或多個(gè)字符 + 表示后面可跟 1 個(gè)或多個(gè)字符 ? 表示后面可跟 0 個(gè)或 1 個(gè)字符 {n,m}表示后面可跟n到m個(gè)字符

例如,匹配11個(gè)字符的電話(huà)號(hào)碼。
這個(gè)使用方法很簡(jiǎn)單,大家多練習(xí)使用即可。但這里有一個(gè)很重要的知識(shí)點(diǎn)需要和大家講解下。那就是貪婪模式和非貪婪模式。
以*為例,它可以匹配0個(gè)或多個(gè)字符,那到底是匹配多少個(gè)字符了?貪婪模式就是保證匹配成功的情況下,盡可能多的匹配,非貪婪模式則反之。默認(rèn)情況下是貪婪模式,如果需要切換為非貪婪模式,就需要在*后面加上?號(hào)。
以
test
為例,如果我們使用<.*>,就會(huì)匹配到test
(.是匹配除換行符之外的任何單個(gè)字符)。
如果使用<.*?>,就會(huì)匹配到
和
。
(3)并列(|) 并列字符很好理解,當(dāng)需要匹配兩個(gè)字符中的一個(gè)的時(shí)候,就用|。A|B,匹配到了A,就不會(huì)查找B。

這里就是匹配到的就是c或者是python。
(4)提取() 如果需要把匹配的字符串提取出來(lái),就需要使用小括號(hào)。這主要使用在編程中,對(duì)數(shù)據(jù)的提取。正如前面的爬蟲(chóng)代碼,用上括號(hào)后,就能將h1標(biāo)簽中的內(nèi)容提取出來(lái)。
import?re
html?=?'''
?test1?
?test2?
?test3?
'''
content?=?re.findall('(.*?)
',?html)
print(content)
#result?['?test1?',?'?test2?',?'?test3?']
在 () 中最前面加入 ?:,代表只匹配不獲取(non-capturing)。
import?re
html?=?'''
?test1?
?test2?
?test3?
'''
content?=?re.findall('(?:.*?)
',?html)
print(content)
#result?['?test1?
',?'?test2?
',?'?test3?
']
其實(shí)這里的?:是是非捕獲元之一,還有兩個(gè)非捕獲元是 ?= 和 ?!,前者為正向預(yù)查,后者為負(fù)向預(yù)查。這兩個(gè)又衍生出?<=和?
A(?=B),匹配符合B條件的A;(?<=B)A,匹配符合B條件的A。前者是匹配的是括號(hào)前面的,后者匹配的是后面的。
windows(?=7|xp|2000|10),能匹配windows7,windowsxp,windows2000,windows10前的windows。

A(?!B),匹配不符合B條件的A;(?
(5)特定意義符號(hào) 就是說(shuō)固定的寫(xiě)法來(lái)代表特定的意義,例如\d代表的就是匹配一個(gè)數(shù)字字符,等同于[0-9]。

以下就是常用的特定意義符號(hào):
| 字符串 | 含義 |
|---|---|
| ^ | 匹配輸入字符串的開(kāi)始位置。 |
| $ | 匹配輸入字符串的結(jié)束位置。 |
| . | 匹配除換行符(\n、\r)之外的任何單個(gè)字符。 |
| \b | 匹配一個(gè)單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
| \B | 匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
| \d | 匹配一個(gè)數(shù)字字符。等價(jià)于 [0-9]。 |
| \D | 匹配一個(gè)非數(shù)字字符。等價(jià)于 [^0-9]。 |
| \f | 匹配一個(gè)換頁(yè)符。 |
| \n | 匹配一個(gè)換行符 |
| \r | 匹配一個(gè)回車(chē)符。 |
| \t | 匹配一個(gè)制表符。 |
| \v | 匹配一個(gè)垂直制表符。 |
| \s | 匹配任何空白字符,包括空格、制表符、換頁(yè)符等等。等價(jià)于 [ \f\n\r\t\v]。 |
| \S | 匹配任何非空白字符。等價(jià)于 [^ \f\n\r\t\v]。 |
| \w | 匹配字母、數(shù)字、下劃線。等價(jià)于'[A-Za-z0-9_]'。 |
| \W | 匹配非字母、數(shù)字、下劃線。等價(jià)于 '[^A-Za-z0-9_]'。 |
\為轉(zhuǎn)義字符,例如\*,就可以匹配*本身。
修飾符(可選標(biāo)記)
學(xué)完前面的元字符后,就算是完成了大部分正則表達(dá)式的知識(shí)點(diǎn)了,也能獨(dú)立使用正則表達(dá)式來(lái)完成日常工作了。之前的截圖中,可以看到gm,他們其實(shí)是修飾符。

修飾符不寫(xiě)在正則表達(dá)式里,標(biāo)記位于表達(dá)式之外,我們來(lái)看下他們代表的意義。
| 修飾符 | 含義 | 具體解釋 |
|---|---|---|
| i | ignore | 匹配時(shí)不區(qū)分大寫(xiě)小 |
| g | global | 全局匹配,查找所有的匹配項(xiàng)。 |
| m | multi line | 多行匹配,使邊界字符 ^ 和 $ 匹配每一行的開(kāi)頭和結(jié)尾。 |
| s | 特殊字符圓點(diǎn) . 中包含換行符 \n | 默認(rèn)情況下的圓點(diǎn) . 是 匹配除換行符 \n 之外的任何字符,加上 s 修飾符之后, . 中包含換行符 \n。 |
這期分享都到這了,下期我們講正則表達(dá)式在日常工作中的使用案例。
更多閱讀
特別推薦

點(diǎn)擊下方閱讀原文加入社區(qū)會(huì)員
