萬事萬物皆正則 -- Java正則表達

一:吹逼前言

正則表達式是很多Javer自動忽略的知識點,不可否認具備一定的難度,並且在線正則生成的開源也催化了這種現象的普遍性。前段時間偶然聽說一則新聞某知名IT大神吐槽不會正則的程序員不配稱呼程序員,正則表達式的運用場景屬實在編程中廣泛存在。不求精通,但求略懂。至少需要達到當遇到一個不是很複雜正則我們可以進行解析,編輯正則還是在線生成吧。開源還是存在一定邏輯,手擼正則誰知道是什麼情況

二:Java支持

Java在JDK1.4增加了對正則表達式的支持,也就是java.util.regex包,下面常用的兩個類爲Patter與Matcher。Patter負責解析正則表達式,Matcher負責將字符與表達式進行匹配。其中Patter未提供public的構造函數,依賴方法compile()返回對象實例,Matcher對象實例依靠Patter類matcher()返回,簡易操作示例如下:
在這裏插入圖片描述
需要注意一點就是目前Java中字符串的匹配還是交給String類的matches()方法完成,不必進行如此複雜的操作。查看String類的該方法源碼如下,發現還是調用Patter類的靜態方法matches()
在這裏插入圖片描述

三:基礎規則

因爲本文是根據Java基礎進行講解,需要注意特別的一點。總所周知".“在正則中匹配所有單字符出\n外,如果想讓其表示一般文本語義,則需要使用轉義符號”\"。注意這個轉義符號在Java中也需要使用"\“進行轉義,也就是最後的呈現方式爲”\\."

3.1 限定符

限定符也就是限制給定組件可以出現的次數,注意限定符必須出現在普通字符或非打印字符之後,也就是不能單獨出現,且限定符只能限制前一個字符的範圍

符號 含義
? 0或者1個字符
* 0或者多個字符
+ 1或者無數個字符
{m,n} 最少m個,最多n個,n爲空代表無數多

在這裏插入圖片描述
解釋一下什麼叫限制前一個字符,如下示例。限定符{3,4}只是限制字符b出現的次數,而不能限制a,那麼a還是隻能出現這一次。所以最後結果爲false
在這裏插入圖片描述

3.2 一組字符

在這裏插入圖片描述
想要讓某個位置出現很多種情況,例如可能是1、2、5、a、A怎麼辦?如上所示,這時候使用中括號“[]“”表示一組字符

3.3 數字元字符

在這裏插入圖片描述
如果想要表達一個字符是數字,可以採取的方式有如下幾種,注意其中的"-“不在”[]"中只能表示普通字符,不能表示範圍:

  • [0-9]:表示數字0-9都可以匹配
  • \d:等同於[0-9]
  • \D:表示非數字,與前兩者相反
3.4 字母元字符

在這裏插入圖片描述
如果想要表達一個字符爲字母,那麼就有如下幾種方式,與數字元字符規則類似:

  • [a-z]:表示a-z的小寫字母
  • [A-Z]:表示A-Z的大小字母
  • [a-zA-Z]:表示大寫字母與小寫字母
3.5 字母或數字或 _

在這裏插入圖片描述
表示數字可以使用\d進行簡寫表示,那麼如果表示大小寫字母、數字、下劃線_可不可以有簡寫呢?肯定有的,如下所示:

  • \w:等同於[a-z0-9A-Z]
  • \W:與上述\w取反
3.6 取反、或

或操作就是要麼是你要麼是我,同或運算語義一致,使用符號"|“表示
在這裏插入圖片描述
取反顧名思義就是槓精,使用尖括號”^“表達內心不要的純粹想法,注意這個取非的語義是在中括號”[]"中使用才具備,其它地方使用表示語義下面講解。同時注意這個取反是針對中括號內部全部取反在這裏插入圖片描述

3.7 組劃分

整個正則表達式可能是多個子級表達式組成,比如最開始講到的匹配年-月-日就是由多個子表達式構成最後的正則表達式。如果需要標記某個子表達式開始與結束使用小括號"()",最經典的使用莫過於子表達式後面跟限定符,表示對整個子表達式進行限定,而非對限定符前一個字符進行限定
在這裏插入圖片描述

3.8 定位符

將正則表達式固定到行首或者是行尾,當然定位符也包括很特殊但是十分重要的單詞邊界定位

符號 含義
^ 匹配輸入字符串開始的位置,千萬不要與中括號裏面的^用法混淆
$ 匹配輸入字符串結束的位置
\b 匹配單詞邊界,即字與空格之間的位置
\B 匹配非單詞邊界

在這裏插入圖片描述
在這裏插入圖片描述

四:反向引用

說直白點就是查緩存,使用"()“的子表達式匹配結果會放到緩存區。當需要複用該結果就可以使用\n複用,其中每個緩存會根據順序按照下標1開始進行存儲,\n中的n指定的就是緩存的下標
在這裏插入圖片描述
如果需要消除掉這個緩存的影響則可以使用”?:"達到目標
在這裏插入圖片描述

五:前瞻與後顧

說直白一點就是看看前面的子表達式匹配的是不是預期或者看看後面的子表達式是否符合預期,有以下幾種表現形式:

  • (?=X):出現位置之後的字符串能匹配X
  • (?<=X):出現位置之前緊跟着的字符串能匹配X
  • (?!X):出現位置之後的字符串不能匹配X
  • (?!<X):出現位置之前的字符串不能匹配X
    在這裏插入圖片描述

六:貪婪與懶惰

在這裏插入圖片描述
兩種正則的解析模式就是字面含義,貪婪儘可能多點、懶惰則儘可能少點。如上圖所示,正則匹配後想看看有多少符合條件的子表達式,就是採用Matcher類的find()與group()方法。其實根據最後的結果來講,理解這兩種正則解析模式就是限定符位置會匹配多少字符串內容。針對這兩種解析模式做出如下總結:

  • 懶惰模式會在滿足正則匹配後不影響後面子字符串的解析匹配,書寫規則爲在限定符後加?
  • 貪婪模式會最大程度的根據正則表達式進行解析匹配,限定符默認爲貪婪模式
  • 這兩種模式下有個共同點都會保證整體文本符合正則表達式解析情況下再發揮特點,這與下面講解的獨佔模式有着本質區別

七:獨佔

在這裏插入圖片描述
獨佔是一個比較特殊的存在,不會對匹配解析進行回溯。結合上圖你會理解這個回溯是什麼意思,即限定符後跟+表示開啓獨佔模式,這時的限定符就會最大程度匹配字符串與貪婪模式一致。但是貪婪模式再貪財也會注意整體大局,也就是示例中匹配到第三個c的時候它發現後面還需要c,如果這個c它匹配了以後整體文本將不會符合正則表達式,這時貪婪模式下會選擇放棄匹配回溯,讓後面的c進行匹配解析。獨佔模式可就不管這些,只要符合的都要,最後整個字符串文本是否符合規則與我無關

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章