正則表達式里匹配次數的元字符有:
(一) {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次以上
總結
量詞本身使用時,都是貪婪模式匹配,而量詞和?能結合成非貪婪模式匹配。
貪婪模式匹配就是盡可能多地匹配,非貪婪模式匹配就是盡可能少地匹配。
