半小時(shí)學(xué)會(huì)正則表達(dá)式(上)

半小時(shí)學(xué)會(huì)正則表達(dá)式(上)

正則表達(dá)式(Regular Expression)在代碼中常常簡寫為regex。正則表達(dá)式通常被用來檢索、替換那些符合某個(gè)規(guī)則的文本,它是一種強(qiáng)大而靈活的文本處理工具。

正則描述了一個(gè)規(guī)則,通過這個(gè)規(guī)則可以匹配一類字符串。

如何學(xué)習(xí)正則?

1、學(xué)習(xí)正則表達(dá)式的語法規(guī)則
2、練習(xí)使用正則并能解決實(shí)際問題

針對(duì)上面的每個(gè)點(diǎn)我會(huì)分別寫一篇文章來說明,用最短的時(shí)間學(xué)會(huì)正則表達(dá)式。

這篇文章講述正則表達(dá)式的語法和使用說明,讓你半小時(shí)學(xué)會(huì)正則表達(dá)式。

學(xué)習(xí)正則表達(dá)式語法,主要就是學(xué)習(xí)元字符以及它們?cè)谡齽t表達(dá)式上下文中的行為。

為了便于理解,文章所有示例的正則表達(dá)式用“regex=正則”表示,“=”號(hào)后面就是正則表達(dá)式,匹配到的字符會(huì)用顏色標(biāo)注出來,連續(xù)匹配到的字符用一深一淺兩種顏色區(qū)分。比如:regex=\d+,其中\(zhòng)d+就是一個(gè)正則,它匹配任意多于1個(gè)的數(shù)字,如下:

regex=\d+匹配的字符串

正則表達(dá)式語法匯總

元字符:
普通字符、標(biāo)準(zhǔn)字符、特殊字符、限定字符(量詞)、定位字符(邊界字符)。

普通字符:
字母[a-zA-Z]、數(shù)字[0-9]、下劃線[-]、漢字,標(biāo)點(diǎn)符號(hào)

匹配字母a可以regex=a
匹配字母b可以regex=b
匹配字母a或者b可以regex=a|b,這個(gè)正則引入一個(gè)特殊字符“|”,專業(yè)名稱為“或”,你也可以叫它“豎線”,總之它表示“或”的意思。

匹配字母a或者b或者c可以regex=a|b|c
匹配字母a或者b或者c或者d可以regex=a|b|c|d
明顯發(fā)現(xiàn)這么寫有點(diǎn)傻了,如果匹配所有26個(gè)字母,這種寫法就太二了。

這里引入兩個(gè)特殊字符方括號(hào)“[ ]”和中劃線“-”
“[ ]”,專業(yè)名稱為“字符集合”,你也可以叫它“方括號(hào)”。
“-”,表示“范圍”,你也可以叫它“到”,regex=[a-z]匹配從a到z26個(gè)字母的任意一個(gè)。

那么匹配字母a或者b或者c或者d可以regex=[abcd]
匹配數(shù)字1到8的任意數(shù)字可以regex=[1-8],這樣就不會(huì)匹配到0與9這2個(gè)數(shù)字了,如下:

regex=[1-8]匹配的字符串

標(biāo)準(zhǔn)字符集合:
標(biāo)準(zhǔn)字符集合是能夠與“多種普通字符”匹配的簡單表達(dá)式,比如:\d、\w、\s

匹配數(shù)字0到9的任意數(shù)字可以regex=[0-9]也可以regex=\d
標(biāo)準(zhǔn)字符集要注意區(qū)分大小寫,大寫是相反的意思
regex=\D,則匹配非數(shù)字字符,即不能匹配數(shù)字0到9,如下:

regex=\D匹配的字符串

下面是一些常用的標(biāo)準(zhǔn)字符說明

標(biāo)準(zhǔn)字符 含義
\d 匹配0-9中的任意一個(gè)數(shù)字,等效于[0-9]
\D 匹配非數(shù)字字符,等效于[^0-9]
\w 匹配任意一個(gè)字母、數(shù)字或下劃線,等效于[^A-Za-z0-9_]
\W 與任何非字母、數(shù)字或下劃線字符匹配,等效于[^A-Za-z0-9_]
\s 匹配任何空白字符,包括空格、制表符、換頁符,等效于 ?[\f\n\r\t\v]
\S 匹配任何非空白字符,等效于[^\f\n\r\t\v]
\n 匹配換行符
\r 匹配一個(gè)回車符
\t 匹配制表符
\v 匹配垂直制表符
\f 匹配換頁符

特殊字符:
這些字符在正則表達(dá)式中表示特殊的含義,比如:*,+,?,\,等等

“\”是轉(zhuǎn)義字符,用于匹配特殊字符

匹配反斜杠“\”可以regex=\\,因?yàn)椤癨”是特殊字符,所以需要在它前邊再加一個(gè)“\”進(jìn)行轉(zhuǎn)義

匹配星號(hào)“*”,可以regex=\*,因?yàn)椤?”是特殊字符,所以需要在它前邊再加一個(gè)“\”進(jìn)行轉(zhuǎn)義

下面是一些常用的特殊字符說明,后面都會(huì)講到

特殊字符 含義
\ 轉(zhuǎn)義字符,將下一個(gè)字符標(biāo)記為一個(gè)特殊字符
^ 匹配字符串開始的位置
$ 匹配字符串結(jié)尾的位置
* 零次或多次匹配前面的字符或子表達(dá)式
+ 一次或多次匹配前面的字符或子表達(dá)式
? 零次或一次匹配前面的字符或子表達(dá)式
. “點(diǎn)” 匹配除“\r\n”之外的任何單個(gè)字符
|
[ ] 字符集合
( ) 分組,要匹配圓括號(hào)字符,請(qǐng)使用 “(” ?或 “)”

限定字符(量詞)
限定字符又叫量詞,是用于表示匹配的字符數(shù)量的。

匹配任意1位數(shù)字可以regex=\d
匹配任意2位數(shù)字可以regex=\d\d
匹配任意3位數(shù)字可以regex=\d\d\d

匹配任意16位數(shù)字,再這么寫就有點(diǎn)傻了
這里引入用于表示數(shù)量限定字符“{n}”
{n},n是一個(gè)非負(fù)整數(shù),匹配確定的n次

注意:regex=\d\d{3}匹配任意4個(gè)數(shù)字不是6個(gè),量詞只對(duì)它前面的字符負(fù)責(zé),regex=\d\d{3}匹配的內(nèi)容如下:

regex=\d\d{3}匹配的字符串

匹配任意16位數(shù)字可以regex=\d{16}
匹配任意16位以上的數(shù)字可以regex=\d{16,}
匹配任意1到16位以上的數(shù)字可以regex=\d{1,16}

regex=\d{1,16}匹配到的字符串

從上圖,我們可以看到regex=\d{1,16},可以匹配到任意1-16個(gè)數(shù)字

下面介紹一下匹配次數(shù)中的貪婪模式與非貪婪模式

正則的匹配默認(rèn)是貪婪模式,即匹配的字符越多越好,
非貪婪模式是匹配的字符越少越好,在修飾匹配字?jǐn)?shù)的量詞后再加上一個(gè)問號(hào)“?”即可。

那么同樣是上面的字符串,regex=\d{1,16}?匹配到什么呢?

regex=\d{1,16}?匹配到的字符串

因?yàn)樵趝1,16}這個(gè)量詞后面加上了問號(hào)“?”,表示非貪婪模式,所以只能匹配到1個(gè)數(shù)字,即匹配的字符越少越好。

下面是一些常用的限定字符說明

限定字符 含義
* 零次或多次匹配前面的字符或子表達(dá)式
+ 一次或多次匹配前面的字符或子表達(dá)式
? 零次或一次匹配前面的字符或子表達(dá)式
{n} n是一個(gè)非負(fù)整數(shù),匹配確定的n次
{n,} n是非負(fù)整數(shù),至少匹配n次
{n,m} n和m是非負(fù)整數(shù),其中n<=m;匹配至少n次,至多m次

匹配0個(gè)或多個(gè)字母A可以regex=A*或者regex=A{0,}
匹配至少一個(gè)字母A可以regex=A+或者regex=A{1,}
匹配0個(gè)或1字母A可以regex=A?或者regex=A{0,1}

匹配至少一個(gè)LOVE可以regex=(LOVE)+,匹配的效果如下:

regex=(LOVE)+匹配到的字符串

定位字符(字符邊界)
定位字符也叫字符邊界,標(biāo)記匹配的不是字符而是符合某種條件的位置,所以定位字符是“零寬的”。

下面是一些常用的定位字符說明

定位字符 含義
^ 匹配字符串開始的位置,表示開始
$ 匹配字符串結(jié)尾的位置,表示結(jié)尾
\b 匹配一個(gè)單詞邊界

匹配以Hello開頭的字符串可以regex=^Hello

regex=^Hello匹配到的字符串

匹配以Hello結(jié)尾的字符串可以regex=Hello$,如下:

regex=Hello$匹配到的字符串

匹配以H開頭以o結(jié)尾的任意長度字符串可以regex=^H.*o$,如下:

regex=^H.*o$匹配到的字符串

\b匹配這樣一個(gè)位置:前面的字符和后面的字符不全是\w
如果在“hello,hello1 hello hello1 bhello”這個(gè)字符串里匹配regex=hello\b,
匹配到的結(jié)果如下:

regex=hello\b匹配到的字符串

分析一下:為什么hello1匹配不了“hello\b”這個(gè)正則?

首先\b是一個(gè)定位字符,它是零寬的,標(biāo)識(shí)一個(gè)位置,這個(gè)位置的前面和這個(gè)位置的后面不能全是\w,即不能全是字母數(shù)字和下劃線[A-Za-z0-9_],而hello1的o與1之間的位置前面是o后面是1,前后全是\w,不符合\b匹配的含義,因此hello1不能匹配正則表達(dá)式“hello\b”

但是bhello可以匹配“hello\b”這個(gè)正則,因?yàn)閔ello的結(jié)尾的位置,前面是o,后面是空白,所以符合\b匹配的含義,因此bhello可以匹配“hello\b”這個(gè)正則。

自定義字符集合:
方括號(hào)[ ]表示字符集合,即[ ]表示自定義集合,用[ ]可以匹配方括號(hào)里的任意一個(gè)字符。

regex=[aeiou]匹配“a”,“e”,“i”,“o”,“u”任意一個(gè)字符,也就是可以匹配集合[aeiou]的任意一個(gè)字符。

但是,特殊字符(除了小尖角“^和中劃線“-)被包含到方括號(hào)中,就會(huì)失去特殊意義,只代表其字符本身。

regex=[abc+?]匹配“a”,“b”,“c”任意一個(gè)字符或者“+”,“*”,“?”,即包含在自定義集合中的特殊字符“+”,“*”,“?”*失去了特殊含義,只表示其字符本身的意思。

特殊字符小尖角“^”,原本含義是匹配字符串的開始位置,如果包含在自定義集合[ ]中,則表示取反的意思。
比如:regex=[^aeiou]匹配“a”,“e”,“i”,“o”,“u”之外的任意一個(gè)字符。

中劃線“-”,在自定義集合[ ]中,表示“范圍”,而不是字符“-”本身,regex=[a-z],匹配從a到z中26個(gè)字母的任意一個(gè)。

除小數(shù)點(diǎn)“.”外,標(biāo)準(zhǔn)字符集合包含在方括號(hào)中,仍然表示集合范圍。
regex=[\d.+]匹配0-9的任意一個(gè)數(shù)字或者小數(shù)點(diǎn)“.”或者加號(hào)“+”

也就是說\d在自定義集合中仍然表示數(shù)字,但是小數(shù)點(diǎn)在字符集合中只表示小數(shù)點(diǎn)本身,而不是除“\r\n”之外的任何單個(gè)字符。

選擇符和分組

表達(dá)式 作用
pattern1|pattern2 或的關(guān)系,匹配左邊的pattern1或右邊的pattern2
(pattern) 匹配pattern并獲取這一匹配,并存儲(chǔ)
(?:pattern) 匹配pattern但不獲取匹配結(jié)果,也就是不進(jìn)行存儲(chǔ)

regex=x|y,匹配字符x或y。

( )表示捕獲組,( )的作用如下:
1、括號(hào)中的表達(dá)式可以作為整體被修飾,用來表示匹配括號(hào)中表達(dá)式的次數(shù),regex=(abc){2,3},可以匹配連續(xù)的2個(gè)或3個(gè)abc,如下:

regex=(abc){2,3}匹配到的字符串

2、括號(hào)中的表達(dá)式匹配到的內(nèi)容會(huì)存儲(chǔ)起來,并可以獲取到括號(hào)中表達(dá)式匹配到的內(nèi)容
3、每一對(duì)括號(hào)會(huì)分配一個(gè)編號(hào),使用( )的捕獲根據(jù)左括號(hào)的順序從1開始自動(dòng)編號(hào),編號(hào)為0的捕獲是整個(gè)正則表達(dá)式匹配到的文本。

捕獲組( )可以把匹配的內(nèi)容存儲(chǔ)起來,那么如何獲取( )捕獲到的內(nèi)容呢,下面介紹反向引用。

反向引用“\number”
每一對(duì)括號(hào)會(huì)分配一個(gè)編號(hào),使用( )的捕獲根據(jù)左括號(hào)的順序從1開始自動(dòng)編號(hào)。通過反向引用,可以對(duì)分組已捕獲的字符串進(jìn)行引用。
“\number”中的number就是組號(hào)

regex=(abc)d\1可以匹配字符串a(chǎn)bcdabc,即\1表示把獲取到的第一組再匹配一次,如下:

regex=(abc)d\1匹配到的字符串

(?:pattern)表示非捕獲組,匹配括號(hào)中表達(dá)式匹配到的內(nèi)容,但是不進(jìn)行存儲(chǔ)匹配到的內(nèi)容。這在使用 "或" 字符?(|)?來組合一個(gè)正則的各個(gè)部分是很有用的。

例如:匹配字符“story”或者“stories”,regex=stor(?:y|ies)就是一個(gè)比 regex=story|stories更簡略的表達(dá)式。

預(yù)搜索(零寬斷言)
預(yù)搜索,又叫零寬斷言,又叫環(huán)視,它是對(duì)位置的匹配,與定位字符(邊界字符)類似。

表達(dá)式 作用
(?=pattern) 斷言此位置的后面能匹配表達(dá)式pattern
(?<=pattern) 斷言此位置的前面能匹配表達(dá)式pattern
(?!pattern) 斷言此位置的后面不能匹配表達(dá)式pattern
(?<!pattern) 斷言此位置的前面不能匹配表達(dá)式pattern

regex=love (?=story)匹配的結(jié)果如下(匹配“l(fā)ove?”后面是story):

regex=love (?=story)匹配到的字符串

regex=love (?!story)匹配的結(jié)果如下(匹配“l(fā)ove ”后面不能是story):

regex=love (?!story)匹配到的字符串

運(yùn)算符的優(yōu)先級(jí)
正則表達(dá)式從左到右進(jìn)行計(jì)算,并遵循優(yōu)先級(jí)順序,這與算術(shù)表達(dá)式非常類似。

下表的優(yōu)先級(jí)從高到低排序

運(yùn)算符 描述
\ 轉(zhuǎn)義字符
(), (?:), (?=), [] 圓括號(hào)和方括號(hào),分組和自定義集合
*, +, ?, {n}, {n,}, {n,m} 限定字符(量詞)
^, $, 標(biāo)準(zhǔn)字符,字符 定位字符(邊界字符)和字符
|

說明:“|”或操作是優(yōu)先級(jí)最低的,它比普通字符的優(yōu)先級(jí)低。
因此,regex=r|loom匹配“r”或“l(fā)oom”,如下:

regex=r|loom匹配到的字符串

如果想匹配“room”或“l(fā)oom”,請(qǐng)用括號(hào)創(chuàng)建子表達(dá)式,regex=(r|l)oom,如下:

regex=(r|l)oom匹配到的字符串

至此,正則表達(dá)式的語法介紹完了,大家是不是已經(jīng)掌握了呢,趕快去體驗(yàn)一下吧。

最后給大家介紹一下開發(fā)中使用正則表達(dá)式的流程:
1、分析所要匹配的數(shù)據(jù)特點(diǎn),模擬各種測試數(shù)據(jù);
2、利用正則工具,寫正則表達(dá)式與測試數(shù)據(jù)進(jìn)行匹配,從而驗(yàn)證你寫的正則;
3、在程序里調(diào)用在正則工具中驗(yàn)證通過的正則表達(dá)式。

在這里給大家推薦一個(gè)正則工具“RegexBuddy”,你可以從網(wǎng)上下載,或者回復(fù)關(guān)鍵詞“正則表達(dá)式”獲取。

《半小時(shí)學(xué)會(huì)正則表達(dá)式(下)》會(huì)講解學(xué)習(xí)正則表達(dá)式的第二部分,練習(xí)使用正則并解決一些實(shí)際問題,敬請(qǐng)關(guān)注后續(xù)內(nèi)容。

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

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

  • 正則表達(dá)式到底是什么東西?字符是計(jì)算機(jī)軟件處理文字時(shí)最基本的單位,可能是字母,數(shù)字,標(biāo)點(diǎn)符號(hào),空格,換行符,漢字等...
    獅子挽歌閱讀 2,161評(píng)論 0 9
  • 推薦幾個(gè)正則表達(dá)式編輯器 Debuggex :https://www.debuggex.com/ PyRegex:...
    木易林1閱讀 11,525評(píng)論 9 151
  • 注:本篇文章只為方便查看,特此保留,如有冒犯,敬請(qǐng)諒解!!! 本文目標(biāo) 30分鐘內(nèi)讓你明白正則表達(dá)式是什么,并對(duì)它...
    阿杰Alex閱讀 1,501評(píng)論 0 10
  • 初衷:看了很多視頻、文章,最后卻通通忘記了,別人的知識(shí)依舊是別人的,自己卻什么都沒獲得。此系列文章旨在加深自己的印...
    DCbryant閱讀 4,039評(píng)論 0 20
  • 幾個(gè)正則表達(dá)式編輯器 Debuggex :https://www.debuggex.com/ PyRegex:ht...
    沒技術(shù)的BUG開發(fā)攻城獅閱讀 4,613評(píng)論 0 23