正則表達式(二)
量詞
量詞的通用形式
字符組和字符組簡記都是只能匹配一個字符,那如果需要匹配一個身份證號呢?那就需要多次重復使用字符組或者字符組簡記,量詞的存在便是為了解決重復的讀寫問題。量詞的通用形式為{m,n},m,n為數字,限定字符組中字符存在的個數,閉區間,m為下限,n為上限。如\d{3,5}表示匹配字符串的長度最少為3,最大為5。
通用形式 | 描述 |
{n} | 匹配字符串長度為n |
{m,n} | 匹配字符串長度最小為m,最大為n |
{m,} | 匹配字符串長度最小為m,最大為無窮 |
{0,n} | 匹配字符串長度最小為空,最大為n |
常用量詞
{m,n}為量詞通用形式,正則中還存在其他量詞,分別為+、*、?。常用於具體元素后,表示出現次數。如:a+表示a會存在且至少出現一次。
常用量詞 | {m,n}等效形式 | 描述 |
+ | {1,} | 出現次數大於等於1 |
* | {0,} | 出現次數大於等於0 |
? | {0,1} | 出現次數為0或者1 |
點號
點號是一個特殊的元字符,可以匹配任意字符,除了空白字符中的換行符\n。所以點號並不是真正意義上的匹配任意字符,匹配任意字符有兩種方法:
1.在單行匹配模式下,點號可以匹配任意字符。
2.使用通配字符組[\d\D]、[\w\W]、[\s\S]可以匹配任意字符。
任意字符是指任意單個字符,所有任意字符則是指多個任意字符。如何匹配所有任意字符呢?可以使用:.*或者[\d\D]*、[\w\W]*、[\s\S]*。
.*匹配所有任意字符問題
任意給定字符串"string",使用正則表達式 ".*"進行匹配,匹配流程為:正則“匹配字符串“,之后.*匹配s、t、r、i、n、g,最后字符串尾”是由正則的.*匹配還是由”匹配?
回答這個問題之前,需要明白量詞可以划分為貪婪量詞和非貪婪量詞。之前接觸的量詞都是貪婪量詞,具體表現就是:能匹配的都匹配,每匹配一個就記錄當前狀態,方便匹配最后出現問題回檔。上面問題的實際過程是:.*會匹配字符串尾的”,並且記錄匹配狀態,匹配完發現字符串結束了,但是正則表達式還剩余一個”沒有匹配,這就出了問題了,考慮要照顧正則中”,.*需要查看自己的匹配狀態,找到自己匹配的字符串中”,然后回檔,讓正則”匹配字符串中的”。這種“貪吃出問題又吐出來”的過程稱之為回溯。
貪婪量詞:能匹配上的都匹配上,出了問題再回溯,回溯過程是把吃了的吐出來。
非貪婪量詞:能匹配上的匹配一次就夠,剩下字符串讓后續正則字符組匹配,出了問題也回溯,回溯過程是把沒吃的吃進去。
貪婪量詞 | 非貪婪量詞 |
* | *? |
+ | +? |
? | ?? |
{m,n} | {m,n}? |
{m,} | {m,}? |
{0,n} | {0,n}? |
非貪婪量詞和貪婪量詞逐一對應,只是在對應的貪婪量詞后加上?,兩者表達的意思也是一致,遇到不能匹配的情況都需要回溯。唯一區別在於:貪婪量詞面對能匹配的情況優先選擇“匹配”,非貪婪量詞面對能匹配的情況優先選擇“推讓”。
轉義
量詞分為貪婪量詞、非貪婪量詞,又補充了點號,這些特殊含義的字符在匹配原本自身的時候,需要使用\轉義。如\*、\{m,n}、\+\?等等。