一文弄懂正則表達式

前言

如果說什么是我學習編程來最好用顾稀,最常用的知識點苟呐,那應該就是正則表達式了痒芝。嚴謹?shù)恼f,正則表達式并不是一門編程語言牵素,也不是為了一種編程語言而服務的知識严衬。但他確實足夠好用,應用也足夠廣泛笆呆。

例如可以在文本中提取規(guī)則的電話號碼请琳,電子郵箱。
在office中的通配符也是正則表達式哦赠幕,這樣在office中做規(guī)則的搜索和替換俄精,也是能極高的提升工作效率。

正則表達式在爬蟲中也經常使用到榕堰,例如只需要簡單的幾行代碼竖慧,就可以獲取h1標簽下的所有內容。

import re
html = '''
<h1> test1 </h1>
<h1> test2 </h1>
<h1> test3 </h1>
'''
content = re.findall('<h1>(.*?)</h1>', html)
print(content)

#result [' test1 ', ' test2 ', ' test3 ']

那正則表達式到底是什么逆屡,又該如何使用圾旨,為什么我們爬蟲中老是使用(.*?),它到底起到了什么作用魏蔗,這篇文章就詳細告訴你砍的。

什么是正則表達式

正則表達式(regular expression)描述了一種字符串匹配的模式(pattern),聽起來確實不是很好理解莺治。

我們從這個定義中抽出三個關鍵詞:

  • 字符串:這個定義了使用的對象挨约,也就是文本。
  • 匹配:定義了用途产雹,用于查找定位诫惭。
  • 模式:模式其實就是規(guī)則,這就是正則表達式的核心蔓挖,這里的規(guī)則是人為定義好的夕土,可以是字符,數(shù)字和字母。

所以用大白話來說怨绣,正則表達式就是一些人為定義的規(guī)則角溃,進行組合,使其具有快速匹配字符串的功能篮撑。

元字符

前面說到正則表達式就是一些定義好的規(guī)則的組合减细,這個規(guī)則背后就是元字符。

元字符有很多赢笨,我們按用途將他們分為5類未蝌,便于理解和使用。

  • 集合:[ ]
  • 次數(shù):表示次數(shù):* + ? {}
  • 并列:|
  • 提燃攵省:()
  • 特定意義符號:. ^ $ \b\B

本篇文章的實例都在該網站上在線驗證:https://regex101.com/
(1)集合([ ])
[ ]表示匹配所包含的任意一個字符萧吠,例如[Pp]ython,就能匹配Python和python桐筏。

在集合中使用-纸型,可以匹配一個范圍內的字符,例如[a-z]可以匹配a到z任意一個字符梅忌。

使用 ^ 可以匹配補集狰腌,例如[^p]ython,就能匹配除了p之外的字符牧氮。

(2)次數(shù)字符
上面的正則表達式只能匹配一個字符癌别,這時你就需要次數(shù)相關的字符。

  • * 表示后面可跟 0 個或多個字符
  • + 表示后面可跟 1 個或多個字符
  • ? 表示后面可跟 0 個或 1 個字符
  • {n,m}表示后面可跟n到m個字符

例如,匹配11個字符的電話號碼。


這個使用方法很簡單蔗彤,大家多練習使用即可。但這里有一個很重要的知識點需要和大家講解下圾笨。那就是貪婪模式和非貪婪模式。

以*為例逊谋,它可以匹配0個或多個字符擂达,那到底是匹配多少個字符了?貪婪模式就是保證匹配成功的情況下胶滋,盡可能多的匹配板鬓,非貪婪模式則反之。默認情況下是貪婪模式究恤,如果需要切換為非貪婪模式俭令,就需要在*后面加上?號部宿。

以<h1>test</h1>為例抄腔,如果我們使用<.*>瓢湃,就會匹配到<h1>test</h1>(.是匹配除換行符之外的任何單個字符)。

如果使用<.*?>赫蛇,就會匹配到<h1>和</h1>绵患。

(3)并列(|)
并列字符很好理解,當需要匹配兩個字符中的一個的時候悟耘,就用|落蝙。A|B,匹配到了A暂幼,就不會查找B筏勒。

這里就是匹配到的就是c或者是python。

(4)提取()
如果需要把匹配的字符串提取出來粟誓,就需要使用小括號。這主要使用在編程中起意,對數(shù)據(jù)的提取鹰服。正如前面的爬蟲代碼,用上括號后揽咕,就能將h1標簽中的內容提取出來悲酷。

import re
html = '''
<h1> test1 </h1>
<h1> test2 </h1>
<h1> test3 </h1>
'''
content = re.findall('<h1>(.*?)</h1>', html)
print(content)

#result [' test1 ', ' test2 ', ' test3 ']

在 () 中最前面加入 ?:,代表只匹配不獲惹咨啤(non-capturing)设易。

import re
html = '''
<h1> test1 </h1>
<h1> test2 </h1>
<h1> test3 </h1>
'''
content = re.findall('<h1>(?:.*?)</h1>', html)
print(content)

#result ['<h1> test1 </h1>', '<h1> test2 </h1>', '<h1> test3 </h1>']

其實這里的?:是是非捕獲元之一,還有兩個非捕獲元是 ?= 和 ?!蛹头,前者為正向預查顿肺,后者為負向預查。這兩個又衍生出?<=和?<!渣蜗。接下來我們就看看他們的具體使用方法吧屠尊。

A(?=B),匹配符合B條件的A耕拷;(?<=B)A讼昆,匹配符合B條件的A。前者是匹配的是括號前面的骚烧,后者匹配的是后面的浸赫。

windows(?=7|xp|2000|10),能匹配windows7赃绊,windowsxp既峡,windows2000,windows10前的windows碧查。

A(?!B)涧狮,匹配不符合B條件的A;(?<!B)A,匹配不符合B條件的A者冤。前者是匹配的是括號前面的肤视,后者匹配的是后面的。

(5)特定意義符號
就是說固定的寫法來代表特定的意義涉枫,例如\d代表的就是匹配一個數(shù)字字符邢滑,等同于[0-9]。

以下就是常用的特定意義符號:

字符串 含義
^ 匹配輸入字符串的開始位置愿汰。
$ 匹配輸入字符串的結束位置困后。
. 匹配除換行符(\n、\r)之外的任何單個字符衬廷。
\b 匹配一個單詞邊界摇予,也就是指單詞和空格間的位置。例如吗跋, 'er\b' 可以匹配"never" 中的 'er'侧戴,但不能匹配 "verb" 中的 'er'。
\B 匹配非單詞邊界跌宛。'er\B' 能匹配 "verb" 中的 'er'酗宋,但不能匹配 "never" 中的 'er'。
\d 匹配一個數(shù)字字符疆拘。等價于 [0-9]蜕猫。
\D 匹配一個非數(shù)字字符。等價于 [^0-9]哎迄。
\f 匹配一個換頁符回右。
\n 匹配一個換行符
\r 匹配一個回車符。
\t 匹配一個制表符漱挚。
\v 匹配一個垂直制表符楣黍。
\s 匹配任何空白字符,包括空格棱烂、制表符租漂、換頁符等等。等價于 [ \f\n\r\t\v]颊糜。
\S 匹配任何非空白字符哩治。等價于 [^ \f\n\r\t\v]。
\w 匹配字母衬鱼、數(shù)字业筏、下劃線。等價于'[A-Za-z0-9_]'鸟赫。
\W 匹配非字母蒜胖、數(shù)字消别、下劃線。等價于 '[^A-Za-z0-9_]'台谢。

\為轉義字符寻狂,例如\*,就可以匹配*本身朋沮。

修飾符(可選標記)

學完前面的元字符后蛇券,就算是完成了大部分正則表達式的知識點了,也能獨立使用正則表達式來完成日常工作了樊拓。之前的截圖中纠亚,可以看到gm,他們其實是修飾符筋夏。

修飾符不寫在正則表達式里蒂胞,標記位于表達式之外,我們來看下他們代表的意義条篷。

修飾符 含義 具體解釋
i ignore 匹配時不區(qū)分大寫小
g global 全局匹配骗随,查找所有的匹配項。
m multi line 多行匹配拥娄,使邊界字符 ^ 和 $ 匹配每一行的開頭和結尾蚊锹。
s 特殊字符圓點 . 中包含換行符 \n 默認情況下的圓點 . 是 匹配除換行符 \n 之外的任何字符瞳筏,加上 s 修飾符之后, . 中包含換行符 \n稚瘾。

這期分享都到這了,下期我們講正則表達式在日常工作中的使用案例姚炕。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末摊欠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子柱宦,更是在濱河造成了極大的恐慌些椒,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掸刊,死亡現(xiàn)場離奇詭異免糕,居然都是意外死亡,警方通過查閱死者的電腦和手機忧侧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門石窑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蚓炬,你說我怎么就攤上這事松逊。” “怎么了肯夏?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵经宏,是天一觀的道長犀暑。 經常有香客問我,道長烁兰,這世上最難降的妖魔是什么耐亏? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮缚柏,結果婚禮上苹熏,老公的妹妹穿的比我還像新娘。我一直安慰自己币喧,他們只是感情好轨域,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杀餐,像睡著了一般干发。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上史翘,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天枉长,我揣著相機與錄音,去河邊找鬼琼讽。 笑死必峰,一個胖子當著我的面吹牛,可吹牛的內容都是我干的钻蹬。 我是一名探鬼主播吼蚁,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼问欠!你這毒婦竟也來了肝匆?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤顺献,失蹤者是張志新(化名)和其女友劉穎旗国,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體注整,經...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡能曾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了肿轨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寿冕。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖萝招,靈堂內的尸體忽然破棺而出蚂斤,到底是詐尸還是另有隱情,我是刑警寧澤槐沼,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布曙蒸,位于F島的核電站捌治,受9級特大地震影響,放射性物質發(fā)生泄漏纽窟。R本人自食惡果不足惜肖油,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臂港。 院中可真熱鬧森枪,春花似錦、人聲如沸审孽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽佑力。三九已至式散,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間打颤,已是汗流浹背暴拄。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留编饺,地道東北人乖篷。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像透且,于是被迫代替她去往敵國和親撕蔼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內容