正則表達(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ù)字,如下:
正則表達(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ù)字了,如下:
標(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,如下:
下面是一些常用的標(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)容如下:
匹配任意16位數(shù)字可以regex=\d{16}
匹配任意16位以上的數(shù)字可以regex=\d{16,}
匹配任意1到16位以上的數(shù)字可以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}?匹配到什么呢?
因?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)+,匹配的效果如下:
定位字符(字符邊界)
定位字符也叫字符邊界,標(biāo)記匹配的不是字符而是符合某種條件的位置,所以定位字符是“零寬的”。
下面是一些常用的定位字符說明
定位字符 | 含義 |
---|---|
^ | 匹配字符串開始的位置,表示開始 |
$ | 匹配字符串結(jié)尾的位置,表示結(jié)尾 |
\b | 匹配一個(gè)單詞邊界 |
匹配以Hello開頭的字符串可以regex=^Hello
匹配以Hello結(jié)尾的字符串可以regex=Hello$,如下:
匹配以H開頭以o結(jié)尾的任意長度字符串可以regex=^H.*o$,如下:
“\b”匹配這樣一個(gè)位置:前面的字符和后面的字符不全是\w
如果在“hello,hello1 hello hello1 bhello”這個(gè)字符串里匹配regex=hello\b,
匹配到的結(jié)果如下:
分析一下:為什么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,如下:
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表示把獲取到的第一組再匹配一次,如下:
(?: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)匹配的結(jié)果如下(匹配“l(fā)ove ”后面不能是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”,如下:
如果想匹配“room”或“l(fā)oom”,請(qǐng)用括號(hào)創(chuàng)建子表達(dá)式,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)容。