正則表達式里匹配次數的元字符有:
(一) {0,1}
、{0,}
、{1,}
、{3}
逗號前面次數到逗號后面次數
(二) ?
、??
0次或1次
(三) *
0次以上,即0~n
(四) +
1次以上,即1~n
下面深入講解下這幾個元字符的意義:
(一) {0,1}
、{0,}
、{1,}
、{3}
逗號前面次數到逗號后面次數
上面列了幾種都是{}
用於表示次數時常見的寫法。
1. {0,1}
匹配0次或1次
2. {0,}
匹配0次以上,逗號后面為空表示無限次的意思
3. {1,}
匹配1次以上
4. {3}
匹配3次,它是{3,3}
的簡寫形式
需要注意的是,前面數字大於后面數字是會報錯的
有時候會看到[0-9]{1}
這樣的寫法,其實這樣寫也算是多余的,它等價[0-9]
,正則里沒有添加量詞修飾的匹配都是按1次算。
(二) ?
、??
0次或1次
?
匹配0次或1次,可以理解為{0,1}
的簡寫,常見用法有:
1. https?
用於匹配http
或https
2. (https?://)?
用於匹配域名前綴https?://
可有可無的情況。
另外,需要了解的是,?
是匹配優先的,這是什么意思呢?
所謂匹配優先,就是字面意思,能匹配我就先匹配。
下面舉例說明一下:
源碼:www.zjmainstay.cn
正則:^(www\.)?(.+)$
匹配結果是:分組1得到了www.
,分組2得到了zjmainstay.cn
從這里可以看出,對於(www\.)?
部分的正則,它先進行了匹配,然后.+
部分再匹配。
那么,如果我們想要把www.
留給后面的.+
去匹配怎么辦?
我們需要找到一個非匹配優先的方法,對於非匹配優先,接觸過非貪婪模式的讀者可能馬上想到非貪婪模式,不錯,利用非貪婪模式可以解決這個問題:
正則:^(www\.)*?(.+)$
當然,使用正則:^(www\.){0,1}?(.+)$
也是可以的,而且這個更接近原本的意思。
另外,很多人可能沒見過,其實我們還能用:^(www\.)??(.+)$
實現。這里的??
是?
的非匹配優先版本。
(三) *
0次以上,即0~n
*
0次或任意次,可以理解為{0,}
的簡寫,常見用法有:
1. .*
貪婪模式,匹配優先,匹配除換行外的任意字符0次以上
2. .*?
非貪婪模式,非匹配優先,匹配除換行外的任意字符0次以上
3. <a href="/[^"]*"
在href="/"
的雙引號中間,匹配非"
的字符0次以上
大家可能發現,.*?
這里也有?
,但是它已經脫離了前面對?
介紹的0次或1次的范圍,沒錯,只是為了讓大家不至於混淆,我沒有把它歸入上面的?
當中。
我們可以理解為,?
只要跟本文所說的幾個計次量詞結合,就形成非貪婪模式。甚至,連??
你都可以認為是結合后的0次或1次的非貪婪模式,反正也能解釋通不是?
(四) +
1次以上,即1~n
+
與 *
除了匹配次數意義上有所差別,常見用法都類似,它強調的是至少匹配1次以上,可以理解為{1,}
的簡寫。
1. .+
貪婪模式,匹配優先,匹配除換行外的任意字符1次以上
2. .+?
非貪婪模式,非匹配優先,匹配除換行外的任意字符1次以上
3. <a href="/[^"]+"
在href="/"
的雙引號中間,匹配非"
的字符1次以上
總結
量詞本身使用時,都是貪婪模式匹配,而量詞和?
能結合成非貪婪模式匹配。
貪婪模式匹配就是盡可能多地匹配,非貪婪模式匹配就是盡可能少地匹配。