半小時學會正則表達式(上)

正則表達式(Regular Expression)在代碼中經常簡寫爲regex。正則表達式一般被用來檢索、替換那些符合某個規則的文本,它是一種強大而靈活的文本處理工具。正則表達式

正則描述了一個規則,經過這個規則能夠匹配一類字符串。工具

如何學習正則?學習

一、學習正則表達式的語法規則
二、練習使用正則並能解決實際問題測試

針對上面的每一個點我會分別寫一篇文章來講明,用最短的時間學會正則表達式。3d

這篇文章講述正則表達式的語法和使用說明,讓你半小時學會正則表達式。orm

學習正則表達式語法,主要就是學習元字符以及它們在正則表達式上下文中的行爲。blog

爲了便於理解,文章全部示例的正則表達式用「regex=正則」表示,「=」號後面就是正則表達式,匹配到的字符會用顏色標註出來,連續匹配到的字符用一深一淺兩種顏色區分。好比:regex=\d+,其中\d+就是一個正則,它匹配任意多於1個的數字,以下:
排序

regex=\d+匹配的字符串

正則表達式語法彙總開發

元字符:
普通字符、標準字符、特殊字符、限定字符(量詞)、定位字符(邊界字符)。字符串

普通字符:
字母[a-zA-Z]、數字[0-9]、下劃線[-]、漢字,標點符號

匹配字母a能夠regex=a
匹配字母b能夠regex=b
匹配字母a或者b能夠regex=a|b,這個正則引入一個特殊字符「|」,專業名稱爲「或」,你也能夠叫它「豎線」,總之它表示「或」的意思。

匹配字母a或者b或者c能夠regex=a|b|c
匹配字母a或者b或者c或者d能夠regex=a|b|c|d
明顯發現這麼寫有點傻了,若是匹配全部26個字母,這種寫法就太二了。

這裏引入兩個特殊字符方括號「[ ]」和中劃線「-」
「[ ]」,專業名稱爲「字符集合」,你也能夠叫它「方括號」。
「-」,表示「範圍」,你也能夠叫它「到」,regex=[a-z]匹配從a到z26個字母的任意一個。

那麼匹配字母a或者b或者c或者d能夠regex=[abcd]
匹配數字1到8的任意數字能夠regex=[1-8],這樣就不會匹配到0與9這2個數字了,以下:

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

標準字符集合:
標準字符集合是可以與「多種普通字符」匹配的簡單表達式,好比:\d、\w、\s

匹配數字0到9的任意數字能夠regex=[0-9]也能夠regex=\d
標準字符集要注意區分大小寫,大寫是相反的意思
regex=\D,則匹配非數字字符,即不能匹配數字0到9,以下:

regex=\D匹配的字符串

下面是一些經常使用的標準字符說明

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

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

「\」是轉義字符,用於匹配特殊字符

匹配反斜槓「\」能夠regex=\\,由於「\」是特殊字符,因此須要在它前邊再加一個「\」進行轉義

匹配星號「*」,能夠regex=\*,由於「*」是特殊字符,因此須要在它前邊再加一個「\」進行轉義

下面是一些經常使用的特殊字符說明,後面都會講到

特殊字符 含義
\ 轉義字符,將下一個字符標記爲一個特殊字符
^ 匹配字符串開始的位置
$ 匹配字符串結尾的位置
* 零次或屢次匹配前面的字符或子表達式
+ 一次或屢次匹配前面的字符或子表達式
? 零次或一次匹配前面的字符或子表達式
. 「點」 匹配除「\r\n」以外的任何單個字符
|
[ ] 字符集合
( ) 分組,要匹配圓括號字符,請使用 「(」 ?或 「)」

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

匹配任意1位數字能夠regex=\d
匹配任意2位數字能夠regex=\d\d
匹配任意3位數字能夠regex=\d\d\d

匹配任意16位數字,再這麼寫就有點傻了
這裏引入用於表示數量限定字符「{n}」
{n},n是一個非負整數,匹配肯定的n次

注意:regex=\d\d{3}匹配任意4個數字不是6個,量詞只對它前面的字符負責,regex=\d\d{3}匹配的內容以下:

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

匹配任意16位數字能夠regex=\d{16}
匹配任意16位以上的數字能夠regex=\d{16,}
匹配任意1到16位以上的數字能夠regex=\d{1,16}

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

從上圖,咱們能夠看到regex=\d{1,16},能夠匹配到任意1-16個數字

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

正則的匹配默認是貪婪模式,即匹配的字符越多越好,
非貪婪模式是匹配的字符越少越好,在修飾匹配字數的量詞後再加上一個問號「?」便可。

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

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

由於在{1,16}這個量詞後面加上了問號「?」,表示非貪婪模式,因此只能匹配到1個數字,即匹配的字符越少越好。

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

限定字符 含義
* 零次或屢次匹配前面的字符或子表達式
+ 一次或屢次匹配前面的字符或子表達式
? 零次或一次匹配前面的字符或子表達式
{n} n是一個非負整數,匹配肯定的n次
{n,} n是非負整數,至少匹配n次
{n,m} n和m是非負整數,其中n<=m;匹配至少n次,至多m次

匹配0個或多個字母A能夠regex=A*或者regex=A{0,}
匹配至少一個字母A能夠regex=A+或者regex=A{1,}
匹配0個或1字母A能夠regex=A?或者regex=A{0,1}

匹配至少一個LOVE能夠regex=(LOVE)+,匹配的效果以下:

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

定位字符(字符邊界)
定位字符也叫字符邊界,標記匹配的不是字符而是符合某種條件的位置,因此定位字符是「零寬的」。

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

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

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

regex=^Hello匹配到的字符串

匹配以Hello結尾的字符串能夠regex=Hello$,以下:

regex=Hello$匹配到的字符串

匹配以H開頭以o結尾的任意長度字符串能夠regex=^H.*o$,以下:

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

\b匹配這樣一個位置:前面的字符和後面的字符不全是\w
若是在「hello,hello1 hello hello1 bhello」這個字符串裏匹配regex=hello\b,
匹配到的結果以下:

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

分析一下:爲何hello1匹配不了「hello\b」這個正則?

首先\b是一個定位字符,它是零寬的,標識一個位置,這個位置的前面和這個位置的後面不能全是\w,即不能全是字母數字和下劃線[A-Za-z0-9_],而hello1的o與1之間的位置前面是o後面是1,先後全是\w,不符合\b匹配的含義,所以hello1不能匹配正則表達式「hello\b」

可是bhello能夠匹配「hello\b」這個正則,由於hello的結尾的位置,前面是o,後面是空白,因此符合\b匹配的含義,所以bhello能夠匹配「hello\b」這個正則。

自定義字符集合:
方括號[ ]表示字符集合,即[ ]表示自定義集合,用[ ]能夠匹配方括號裏的任意一個字符。

regex=[aeiou]匹配「a」,「e」,「i」,「o」,「u」任意一個字符,也就是能夠匹配集合[aeiou]的任意一個字符。

可是,特殊字符(除了小尖角「^和中劃線「-)被包含到方括號中,就會失去特殊意義,只表明其字符自己。

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

特殊字符小尖角「^」,本來含義是匹配字符串的開始位置,若是包含在自定義集合[ ]中,則表示取反的意思。
好比:regex=[^aeiou]匹配「a」,「e」,「i」,「o」,「u」以外的任意一個字符。

中劃線「-」,在自定義集合[ ]中,表示「範圍」,而不是字符「-」自己,regex=[a-z],匹配從a到z中26個字母的任意一個。

除小數點「.」外,標準字符集合包含在方括號中,仍然表示集合範圍。
regex=[\d.+]匹配0-9的任意一個數字或者小數點「.」或者加號「+」

也就是說\d在自定義集合中仍然表示數字,可是小數點在字符集合中只表示小數點自己,而不是除「\r\n」以外的任何單個字符。

選擇符和分組

表達式 做用
pattern1|pattern2 或的關係,匹配左邊的pattern1或右邊的pattern2
(pattern) 匹配pattern並獲取這一匹配,並存儲
(?:pattern) 匹配pattern但不獲取匹配結果,也就是不進行存儲

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

( )表示捕獲組,( )的做用以下:
一、括號中的表達式能夠做爲總體被修飾,用來表示匹配括號中表達式的次數,regex=(abc){2,3},能夠匹配連續的2個或3個abc,以下:

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

二、括號中的表達式匹配到的內容會存儲起來,並能夠獲取到括號中表達式匹配到的內容
三、每一對括號會分配一個編號,使用( )的捕獲根據左括號的順序從1開始自動編號,編號爲0的捕獲是整個正則表達式匹配到的文本。

捕獲組( )能夠把匹配的內容存儲起來,那麼如何獲取( )捕獲到的內容呢,下面介紹反向引用。

反向引用「\number」
每一對括號會分配一個編號,使用( )的捕獲根據左括號的順序從1開始自動編號。經過反向引用,能夠對分組已捕獲的字符串進行引用。
「\number」中的number就是組號

regex=(abc)d\1能夠匹配字符串abcdabc,即\1表示把獲取到的第一組再匹配一次,以下:

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

(?:pattern)表示非捕獲組,匹配括號中表達式匹配到的內容,可是不進行存儲匹配到的內容。這在使用 "或" 字符?(|)?來組合一個正則的各個部分是頗有用的。

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

預搜索(零寬斷言)
預搜索,又叫零寬斷言,又叫環視,它是對位置的匹配,與定位字符(邊界字符)相似。

表達式 做用
(?=pattern) 斷言此位置的後面能匹配表達式pattern
(?<=pattern) 斷言此位置的前面能匹配表達式pattern
(?!pattern) 斷言此位置的後面不能匹配表達式pattern
(?<!pattern) 斷言此位置的前面不能匹配表達式pattern

regex=love (?=story)匹配的結果以下(匹配「love?」後面是story):

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

regex=love (?!story)匹配的結果以下(匹配「love 」後面不能是story):

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

運算符的優先級
正則表達式從左到右進行計算,並遵循優先級順序,這與算術表達式很是相似。

下表的優先級從高到低排序

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

說明:「|」或操做是優先級最低的,它比普通字符的優先級低。
所以,regex=r|loom匹配「r」或「loom」,以下:

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

若是想匹配「room」或「loom」,請用括號建立子表達式,regex=(r|l)oom,以下:

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

至此,正則表達式的語法介紹完了,你們是否是已經掌握了呢,趕快去體驗一下吧。

最後給你們介紹一下開發中使用正則表達式的流程:
一、分析所要匹配的數據特色,模擬各類測試數據;
二、利用正則工具,寫正則表達式與測試數據進行匹配,從而驗證你寫的正則;
三、在程序裏調用在正則工具中驗證經過的正則表達式。

在這裏給你們推薦一個正則工具「RegexBuddy」,你能夠從網上下載,或者回復關鍵詞「正則表達式」獲取。

做者:追夢人_奮鬥青年 連接:https://www.jianshu.com/p/059f8a66c28a 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
相關文章
相關標籤/搜索