Java使用正則表達式-入門篇

正則表達式入門

[提前聲明]
文章由作者:張耀峯 結合自己生產中的使用經驗整理,最終形成簡單易懂的文章
寫作不易,轉載請註明,謝謝!
大數據代碼案例地址: https://github.com/Mydreamandreality/sparkResearch


正則表達式

  • 正則表達式在後端開發中可以說是必備技能之一:數據過濾、數據校驗、數據轉換等等場景都會用到正則表達式,所以在這兒就分享一下正則表達式的基本入門,以及在Java中如何使用正則表達式

元字符

元字符是構造正則表達式的一種基本元素

元字符 說明
. 匹配除了換行符之外的所有字符
\w 匹配字母或數字或下劃線或漢字
\s 匹配任意的空白符
\d 匹配數字
\b 匹配單詞的開始或者結束
^ 匹配字符串的開始
$ 匹配字符串的結束

案例:
匹配abc開頭的字符串

^abc
\babc

匹配11位手機號

^\d\d\d\d\d\d\d\d\d\d\d$

匹配11位手機號,1開頭的

^1\d\d\d\d\d\d\d\d\d\d$

重複限定符

有了元字符就可以寫不少的正則表達式了,但是這樣寫太原始了,看着有些亂,正則沒提供辦法處理這些重複的元字符嗎?

答案是有的!爲了處理這些重複問題,正則表達式中一些重複限定符,把重複部分用合適的限定符替代,下面我們來看一些限定符:

語法 說明
* 重複零次或者更多次
+ 重複一次或者更多次
? 重複0次或者1次
{n} 重複n次
{n,} 重複n次或者更多次
{n,m} 重複n到m次

案例改造:
匹配abc開頭的字符串

^abc
\babc

匹配11位手機號

^\d{11}$

匹配11位手機號,1開頭的

^1\d{10}$

匹配a開頭的,0個或者多個b結尾的字符串

^ab*$

分組

從上面的例子中看到,* 限定符是作用在與他左邊最近的一個字符,那麼問題來了,如果我想要ab同時被*限定那怎麼辦呢?

匹配字符串中包含0到多個ab開頭:

^(ab)*

轉義

正則表達式用小括號來做分組,那麼問題來了:

如果要匹配的字符串中本身就包含小括號,那是不是衝突?應該怎麼辦?

針對這種情況,正則提供了轉義的方式,也就是要把這些元字符、限定符或者關鍵字轉義成普通的字符,做法很簡答,就是在要轉義的字符前面加個斜槓,也就是\即可。

如:要匹配以(ab)開頭:

^(\(ab\))*

條件或

回到我們剛纔的手機號匹配,我們都知道:國內號碼都來自三大網,它們都有屬於自己的號段,比如聯通有130/131/132/155/156/185/186/145/176等號段,假如讓我們匹配一個聯通的號碼,那按照我們目前所學到的正則,應該無從下手的,因爲這裏包含了一些並列的條件,也就是“或”,那麼在正則中是如何表示“或”的呢?

正則用符號 | 來表示或,也叫做分支條件,當滿足正則裏的分支條件的任何一種條件時,都會當成是匹配成功

那麼我們就可以用或條件來處理這個問題

^(130|131|132|155|156|185|186|145|176)\d{8}$

區間

看到上面的例子,是不是看到有什麼規律?是不是還有一種想要簡化的衝動?實際是有的

正則提供一個元字符中括號 [] 來表示區間條件。
限定0到9 可以寫成[0-9]
限定A-Z 寫成[A-Z]
限定某些數字 [165]

優化正則

^((13[0-2])|(15[56])|(18[5-6])|145|176)\d{8}$

現在你已經基本瞭解正則表達式的構成和使用,下面我們演示如何在Java中使用正則表達式

Java中的正則表達式

在Java中要使用正則表達式,需要用到java.util.regex類庫包

它是一個用正則表達式所定製的模式對字符串進行匹配工作

它包含兩個類:Pattern和Matcher

Pattern是一個正則表達式經過編譯後的表現模式

Matcher根據Pattern對象作爲匹配模式對字符串進行匹配

說白了就是Pattern定義正則表達式,Matcher根據定義的正則來過濾字符串

Pattern

Pattern的構造方法是私有的,不可以直接創建,需要使用靜態工廠模式創建:

Pattern.complie(String regex);

matcher

Matcher的構造方法也是私有的,不能直接創建,使用

Pattern.matcher(CharSequence input)

Java代碼示例

    public static List<Integer> matcherNumber(String soap) {
        final String regex = "\\d+";
        Pattern pattern = Pattern.compile(regex);
        Matcher m = pattern.matcher(soap);
        ...暫時先省略部分代碼
    }
  • matches 對所有字符串進行匹配,只有整個字符串都匹配才返回True
  • lookingAt 對前面的字符串能進行匹配,匹配到的字符串在最前面返回True
  • find 對字符串進行匹配,匹配到的字符串可以在任意的位置返回True

Matcher類提供三個匹配操作方法,三個方法均返回boolean類型,當匹配到時返回true,沒匹配到則返回false

  • matches()代碼示例
Pattern p = Pattern.complie("\\d+");
Matcher m = p.matcher("123ddd");
m.matches();  //返回false 

//解釋:
因爲matches要匹配整個字符串才返回true,而(\\d+)這個正則要匹配的是數字,所以文本(123ddd)中的ddd無法被匹配,故返回false

//------------------我是分割線------------------

Matcher m1 = p.matcher("123321");
m1.matches(); //返回true

//解釋:
文本(123321)可以被全部匹配,所以返回True
  • lookingAt()代碼示例
Pattern p = Pattern.complie("\\d+");
Matcher m = p.matcher("ddd123");
m.lookingAt();  //返回false 

//解釋:
因爲matches要匹配到字符串前綴,而(\\d+)這個正則要匹配的是數字,所以文本(ddd123)中的ddd前綴不是數字,無法被匹配,故返回false

//------------------我是分割線------------------

Matcher m1 = p.matcher("123ddd");
m1.lookingAt(); //返回true

//解釋:
文本(123ddd)前綴匹配成功,所以返回True
  • find()代碼示例
Pattern p = Pattern.complie("\\d+");
Matcher m = p.matcher("ddd123");
m.find();  //返回true

//解釋:
在字符串任意位置匹配到了數字,所以返回true

//------------------我是分割線------------------

Matcher m1 = p.matcher("123ddd");
m1.find(); //返回true

//解釋:
在字符串任意位置匹配到了數字,所以返回true

當我們使用以上的匹配模式匹配到數據後,可以使用以下三個方法得到更詳細的信息

  • start() 返回匹配到的子字符串在字符串中的索引位置

  • end() 返回匹配到的子字符串的最後一個字符在字符串中的索引位置

  • group() 返回匹配到的子字符串

  • Java代碼示例
    讓我們把前面的代碼案例補充完整

    public static List<Integer> matcherNumber(String soap) {
        final String regex = "\\d+";
        Pattern pattern = Pattern.compile(regex);
        Matcher m = pattern.matcher(soap);
        List<Integer> result = new ArrayList();
        while(m.find){
            result.add(m.group());
        }
        return result;
    }
    
    //使用
  
    matcherNumber(111aaa222bbb333ccc);
    
    //返回輸出
    List<111,222,333>

堅持看到這裏,相信你已經入門正則表達式,並且能夠在項目中使用了,正則的高級使用方法,後續如果有時間的話會繼續更新!

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