Java基礎(chǔ)進(jìn)階 正則的詳解

1、正則表達(dá)式

在開發(fā)中,通常很多數(shù)據(jù)都會使用String類存儲。原因:操作字符串的功能比較多,比較方便。
在操作String類對象時(shí),會經(jīng)常遇到對字符串進(jìn)行驗(yàn)證的功能,而按照我們之前學(xué)習(xí)的String類,我們使用String類中的諸多函數(shù)是可以完成對字符串校驗(yàn)功能的,但是代碼相對來說比較麻煩,所以在Java中引入正則表達(dá)式的概念來解決上述問題,即簡化代碼。
正則表達(dá)式:專門用于操作字符串的技術(shù),并且可以簡化代碼,用于對字符串的復(fù)雜操作。
正則表達(dá)式弊端:代碼可讀性比較差。

1.1、案例引入

需求:驗(yàn)證QQ號碼是否合法。
分析:
1、第一位不能是零;
2、QQ號碼在5到12之間(包含);
3、QQ號碼都是由數(shù)字組成;

步驟:
1)定義一個(gè)RegexDemo類,在這個(gè)類中定義一個(gè)主函數(shù)main和一個(gè)自定義函數(shù)method_1;
2)在main函數(shù)中調(diào)用自定義函數(shù)method_1;
3)在自定義函數(shù)method_1中定義一個(gè)字符串變量QQ,并賦值為12345;
4)使用if-elseIf-else結(jié)構(gòu)對字符串QQ分別按照上述給定的三個(gè)條件進(jìn)行判斷;
5)使用String類中的charAt()函數(shù)獲取字符串QQ中的第一個(gè)字符和字符0進(jìn)行比較,相等則告訴用戶不能以0開始;
6)使用String類中的length()函數(shù)獲得字符串QQ的長度,判斷是否在5~12之間;
7)驗(yàn)證字符串QQ中是否都是數(shù)字,使用Long.parseLong(QQ)把一個(gè)字符串轉(zhuǎn)成 long 類型的數(shù)據(jù),此函數(shù)容易發(fā)生異常,所以使用try-catch代碼塊對該代碼進(jìn)行捕獲異常處理;

package xuexi.a_regex_demo;
/*
 * 需求:驗(yàn)證QQ號碼是否合法。
 分析:
 1、第一位不能是零;
 2、QQ號碼在5到12之間(包含);
 3、QQ號碼都是有數(shù)字組成;
 */
public class RegexDemo {
    public static void main(String[] args) {
        method_1();
    }
    private static void method_1() {
        // 定義一個(gè)字符串變量
        String QQ = "12345676";
        /*
         * 使用判斷結(jié)構(gòu)判斷字符串是否合法
         */
        // 判斷字符串的第一位是否是0 QQ.charAt(0)表示通過charAt函數(shù)根據(jù)指定的下標(biāo)獲取下標(biāo)對應(yīng)的字符
        if (QQ.charAt(0) == '0') {
            // 說明字符串以0開始
            System.out.println("QQ號碼不能以0開始");
        } else if (QQ.length() < 5 || QQ.length() > 12) {
            // 說明qq的號碼的長度不在5~12之間
            System.out.println("QQ號碼的長度錯(cuò)誤");
        } else {
            /*
             * 說明QQ的號碼一定不是以0開始,并且長度一定在5~12之間,接下來驗(yàn)證是否為數(shù)字
             * 使用包裝類Long中的parseLong()函數(shù)判斷字符串中的字符是否為數(shù)字
             * 如果不為數(shù)字,這個(gè)函數(shù)會拋異常alt+shift+z寫try-catch代碼塊
             */
            try {
                long parseLong = Long.parseLong(QQ);// 將字符串轉(zhuǎn)換為long類型的數(shù)字
                System.out.println("QQ號碼是:" + QQ);
                System.out.println("QQ號碼是:" + parseLong);
            } catch (NumberFormatException e) {
                System.out.println("QQ號碼中有其他非數(shù)字的字符");
            }
        }
    }
}

說明:
1)使用包裝類Long中的parseLong()函數(shù)判斷字符串中的字符是否為數(shù)字。如果不為數(shù)字,這個(gè)函數(shù)會拋異常,既然要拋異常所以寫個(gè)try-catch代碼塊對異常進(jìn)行處理;
2)對某塊代碼進(jìn)行try-catch處理,可以按alt+shift+z快捷鍵生成try-catch代碼塊;
在開發(fā)中字符串是我們使用頻率最高的一類數(shù)據(jù),針對上述程序僅僅就是為了驗(yàn)證一個(gè)字符串中的數(shù)據(jù)是否正確,用上述代碼能夠解決問題,但是代碼很麻煩。在計(jì)算機(jī)語言中針對這類數(shù)據(jù)的驗(yàn)證和其他操作給出了更加簡單的處理方案。
這個(gè)方案就是正則表達(dá)式。正則表達(dá)式它的存在就是用來簡化代碼的書寫,方便完成對字符串的操作。

說明:
1、String類中提供一個(gè)matches()函數(shù),可以判斷字符串對象是否匹配正則表達(dá)式。
1)如果匹配,則返回true;
2)如果不匹配,則返回false;
2、 [1-9]:表示字符串中第一位能夠出現(xiàn)1~9任何一個(gè)數(shù)字;
3、 [0-9]{4,11}:表示字符串中從第2位開始后面的數(shù)字只能出現(xiàn)0~9之間的數(shù)字,并且最少出現(xiàn)4次,最多出現(xiàn)11次;
4、 如果滿足上述條件則返回true,否則返回false

將上述代碼進(jìn)行優(yōu)化,結(jié)果如下:

package xuexi.a_regex_demo;
/*
 * 需求:驗(yàn)證QQ號碼是否合法。
 分析:
 1、第一位不能是零;
 2、QQ號碼在5到12之間(包含);
 3、QQ號碼都是有數(shù)字組成;
 */
public class RegexDemo {
    public static void main(String[] args) {
        method_2();
    }
    // 使用正則表達(dá)式完成QQ號碼的驗(yàn)證
    private static void method_2() {
        // 定義一個(gè)字符串變量
        String QQ = "12345";
        /*
         * String類中提供一個(gè)matches()函數(shù),可以判斷字符串對象是否匹配正則表達(dá)式
         * 如果匹配,則返回true
         * 如果不匹配,則返回false
         * [1-9]:表示字符串中第一位能夠出現(xiàn)1~9任何一個(gè)數(shù)字
         * [0-9]{4,11}:表示字符串中從第2位開始后面的數(shù)字只能出現(xiàn)0~9之間的數(shù)字,并且最少出現(xiàn)4次,最多出現(xiàn)11次
         * 如果滿足上述條件則返回true,否則返回false
         */
        boolean flag = QQ.matches("[1-9][0-9]{4,11}");
        System.out.println(flag);
    }
}

總結(jié):正則表達(dá)式其實(shí)就是通過一些符號簡化了代碼的書寫,其實(shí)底層對應(yīng)的還是代碼,只不過是不用我們程序員來書寫代碼,我們只需要書寫正則表達(dá)式即可完成相應(yīng)的功能。
正則表達(dá)式的弊端:符號越多,閱讀性越差。
所以要想學(xué)習(xí)正則表達(dá)式就得先學(xué)習(xí)一些符號。

1.2、正則表達(dá)式介紹

正則表達(dá)式:正確的規(guī)則組成的一個(gè)表達(dá)式。其實(shí)就是用來簡化字符串的操作。通過一些限定符號組成一種規(guī)則,來驗(yàn)證字符串是否符合規(guī)則
它的功能主要是用來對字符串進(jìn)行各種的操作(驗(yàn)證、匹配、切割、替換,獲取等)。
結(jié)論:正則表達(dá)式只能使用在字符串上。

學(xué)習(xí)正則表達(dá)式:主要是學(xué)習(xí)正則表達(dá)式中的常用符號。
正則表達(dá)式:它是用我們所熟悉的 大括號、中括號 、小括號、字母 、數(shù)字、特殊符號等代替Java代碼對字符串進(jìn)行操作。

1.3、正則表達(dá)式常用符號介紹(掌握)

在api中有正則表達(dá)式的符號介紹:


1.png

我們使用正則表達(dá)式其中一個(gè)重要的功能就是驗(yàn)證字符串中每個(gè)字符是否正確:
學(xué)習(xí)怎么寫一個(gè)正則表達(dá)式去匹配(驗(yàn)證)字符串的每一位。
正則表達(dá)式符號介紹:正則表達(dá)式一般也需要使用字符串進(jìn)行展示:

1、一般符號
x: 指的是普通字符,x代表的是未知數(shù),代表著任何一個(gè)普通字符,舉例x可以代表a,也可以代表b,同時(shí)也可以代表c等普通字符。
舉例說明:"a[1-9][0-9]{4,11}"這里所寫的a就是普通字符x中的一種,這時(shí)x就代表a,那么也就是說此正則表達(dá)式的第一位只能是普通字符a;
\ : 表示反斜線 例:“\” 在正則中就是“\”
\t :制表符。相當(dāng)于tab鍵。

2、給出某個(gè)位置上可以出現(xiàn)的多個(gè)字符
[ ]表示范圍的意思。表示某一位上可以出現(xiàn)的字符數(shù)據(jù),如果正則中需要匹配的某個(gè)字符串中某一位上的字符是唯一的,這時(shí)可以省略中括號。[]還有一個(gè)意思,在正則中還可以表示轉(zhuǎn)義。
[abc] 表示要么是a要么是b還可以是c(只能是其中任意一個(gè))
例:”NBA” 正則:”N[ABC]A” 匹配正確:NBA NAA NCA
[^abc] 當(dāng)前要匹配的某個(gè)字符串中的某一位上不能是a或b 或c(除了a,b,c都可以)
[a-z] 表示26個(gè)小寫字母
[A-Z] 表示26個(gè)大寫字母
[a-zA-Z] 表示26個(gè)大小寫字母
[a-d[m-p]] 當(dāng)前要匹配的某個(gè)字符串中的某一位上 可以是a -d 或 m - p 的字符
[a-d&&[d-f]] 表示只能是d。必須在兩個(gè)范圍中都要符合。(交集)
[a-d&&[^d-f]] 表示只能是a,b,c
[a-z&&[^xyz]] 表示只能是除去x,y,z后的所有小寫字母
[0-9] 表示0~9之間任意數(shù)字

3、提前定義好的一些符號,可以代替上述的[]書寫的范圍


2.png

·點(diǎn) 表示當(dāng)前需要匹配的字符串位置上可以是任意的字符。例:以a開始后面可以是任意字符 “a.”
\d 表示數(shù)字。[0-9] 例:“A[\d]C” 表示A和C之間可以任意的0~9之間的數(shù)字。

說明:為什么在上述正則表達(dá)式“A[\d]C”中書寫\d,而不是直接書寫\d呢?
\d 代表著正則表達(dá)式中的一個(gè)符號,\和d放在一起代表0~9的十個(gè)數(shù)字。一旦將\d書寫在””雙引號中作為字符串,會出現(xiàn)一個(gè)問題,\就會把這個(gè)d轉(zhuǎn)義了,一旦轉(zhuǎn)義就不表示\d是一起的了,那怎么解決這種問題呢?
我們應(yīng)該在\d前面在加一個(gè),如:\d,第一個(gè) \ 表示將第二個(gè) \ 轉(zhuǎn)義成普通的反斜線字符,而變成普通的反斜線之后和d組合就代表著正則中的數(shù)字,所以我們需要這樣寫:”\d” 等同于”[0-9]”
\\ 反斜線字符
\D 表示非數(shù)字。[^0-9]
\w 表示[a-zA-Z_0-9]</tt>。可以是任意數(shù)字、任意大小寫字母、下劃線。
\W 表示[^a-zA-Z_0-9]表示和\w相反。

4、邊界匹配


3.png

^ 表示行的開頭 例:“^h.” 表示只能是以h作為開頭
$ 表示行的結(jié)尾 例:”^h.o$” 表示只能以h作為開頭,以o作來結(jié)尾

5、數(shù)量詞:表示當(dāng)前正則表達(dá)式中某個(gè)規(guī)則可以出現(xiàn)的次數(shù)。注意:數(shù)量詞前面必須有存在正則符號。

5.png

“A?” 表示當(dāng)前需要匹配字符串這個(gè)位置開始往后大寫字母A可以出現(xiàn)零次或一次;

舉例:”[0-9]?”表示在當(dāng)前的字符串位置上0~9之間的任何一個(gè)數(shù)只能出現(xiàn)零次或者一次;
“A*” 表示當(dāng)前需要匹配字符串這個(gè)位置開始往后大寫字母A可以出現(xiàn)零次或多次;

舉例:”[0-9]*”表示在當(dāng)前的字符串位置上0~9之間的任何一個(gè)數(shù)可以出現(xiàn)零次或者一次或者多次;
“A+” 表示當(dāng)前需要匹配字符串這個(gè)位置開始往后大寫字母A可以出現(xiàn)一次或多次;

舉例:”[0-9]+”表示在當(dāng)前的字符串位置上0~9之間的任何一個(gè)數(shù)可以出現(xiàn)一次或者多次;
“A{n}”----> “A{10}” 表示當(dāng)前需要匹配字符串這個(gè)位置開始往后大寫字母A必須出現(xiàn)10次;

舉例:”[0-9]{10}”表示在當(dāng)前的字符串位置上0~9之間的任何一個(gè)數(shù)可以出現(xiàn)10次;
“A{n,}----->”“A{10,}”表示當(dāng)前需要匹配字符串這個(gè)位置開始往后大寫字母A最少出現(xiàn)10次;

舉例:”[0-9]{10,}”表示在當(dāng)前的字符串位置上0~9之間的任何一個(gè)數(shù)最少出現(xiàn)10次;
“A{n,m}”---->“A{10,20}”表示當(dāng)前需要匹配字符串這個(gè)位置開始往后大寫字母A最少出現(xiàn)10次,最多20次;

舉例:”[0-9]{10,20}”表示在當(dāng)前的字符串位置上0~9之間的任何一個(gè)數(shù)最少出現(xiàn)10次,最多20次;


5.png

1.4、正則的功能介紹(掌握)

正則表達(dá)式的主要功能:
它主要是用來對字符串進(jìn)行操作:匹配(驗(yàn)證)、切割、替換、獲取。
正則表達(dá)式需要和String類中的某些函數(shù)結(jié)合使用。

1.4.1、匹配

6.png

根據(jù)指定的正則表達(dá)式匹配字符串,匹配正確返回的是true,匹配錯(cuò)誤,返回false。
需求:驗(yàn)證手機(jī)號碼

分析:手機(jī)號碼的規(guī)則:
1)長度必須是11位;
2)第一位只能是數(shù)字1;
3)第二位可以是3 4 5 7 8;
4)從第三位開始可以是0-9

步驟:
1)定義一個(gè)RegexDemo1類,在這個(gè)類中定義一個(gè)主函數(shù)main;
2)在main函數(shù)中定義一個(gè)String類型的變量tel,并賦值為15066668888;
3)定義一個(gè)手機(jī)號碼的正則規(guī)則regex=”1[34578][0-9]{9}”;
4)使用字符串變量tel調(diào)用String類中的matches()函數(shù),regex正則規(guī)則作為參數(shù)進(jìn)行傳遞,打印結(jié)果;

package xuexi.a_regex_demo;
/*
 * 需求:驗(yàn)證手機(jī)號碼
 分析:手機(jī)號碼的規(guī)則:
 1)長度必須是11位;
 2)第一位只能是數(shù)字1;
 3)第二位可以是3 4 5 7 8;
 4)從第三位開始可以是0-9
 */
public class RegexDemo1 {
    public static void main(String[] args) {
        // 定義一個(gè)字符串
        String tel = "15066668888";
        // 定義一個(gè)手機(jī)號的正則
        String regex = "1[34578][0-9]{9}";
        // 使用字符串對象tel調(diào)用String類中的matches函數(shù),判斷字符串是否匹配正則表達(dá)式
        System.out.println(tel.matches(regex));
    }
}

1.4.2、切割

7.png

需求:使用String類中的split函數(shù)根據(jù)正則表達(dá)式規(guī)則,以數(shù)字對已知的字符串進(jìn)行切割。
1)定義RegexDemo2 類;
2)在這個(gè)類中定義一個(gè)字符串str,并賦值為”sfajs12321dbfj234d23sjfk454sdjf565sdhd757hf”;
3)定義一個(gè)正則表達(dá)式規(guī)則:regex=”\d+”;
4)使用定義好的字符串str調(diào)用split()函數(shù)對正則表達(dá)式進(jìn)行切割;
5)遍歷切割后的數(shù)組;

package xuexi.a_regex_demo;
/*
 * 需求:使用String類中的split函數(shù)根據(jù)正則表達(dá)式規(guī)則,以數(shù)字對已知的字符串進(jìn)行切割。
 1)定義RegexDemo2 類;
 2)在這個(gè)類中定義一個(gè)字符串str,并賦值為”sfljs12321dlfj234d23sjfk454sdjf565sdhd757hf”;
 3)定義一個(gè)正則表達(dá)式規(guī)則:regex=”\\d+”;
 4)使用定義好的字符串str調(diào)用split()函數(shù)對正則表達(dá)式進(jìn)行切割;
 5)遍歷切割后的數(shù)組;
 */
public class RegexDemo2 {
    public static void main(String[] args) {
        // 定義一個(gè)字符串
        String str = "sfajs12321dbfj234d23sjfk454sdjf565sdhd757hf";
        // 定義一個(gè)正則表達(dá)式,以數(shù)字對上述字符串進(jìn)行切割{"sfajs","dbfj","d","sjfk"}
        String regex = "\\d+";
        String[] strs = str.split(regex);
        // 遍歷數(shù)組
        for (int i = 0; i < strs.length; i++) {
            // 打印數(shù)組中的數(shù)據(jù)
            System.out.println(strs[i]);
        }
    }
}

需求:使用String類中的split函數(shù)根據(jù)正則表達(dá)式規(guī)則,以疊詞對已知的字符串進(jìn)行切割。
疊詞:就是重復(fù)出現(xiàn)的字符。
1)在RegexDemo2類中定義一個(gè)method_2函數(shù);
2)在method_2函數(shù)中定義一個(gè)字符串str,并賦值為
”sfljs#######lfj234#######k454sd#####sdhd######hf”;
3)定義一個(gè)正則表達(dá)式規(guī)則:regex=”#+”;
4)使用定義好的字符串str調(diào)用split()函數(shù)對正則表達(dá)式進(jìn)行切割;
5)遍歷切割后的數(shù)組;

public class RegexDemo2 {
    public static void main(String[] args) {
        method_2();
    }
    
    //以同一個(gè)疊詞 切割
    public static void method_2() {
        String str = "sfljs#######lfj234#######k454sd#####sdhd######hf";
        
        String regex = "#{2,}";
        String[] split = str.split(regex);
        
        for (int i = 0 ; i<split.length ; i++) {
            System.out.println(split[i]);
        }
        
    }

1.4.3、正則中的組

需求:以疊詞對已知字符串”sfljs####lfj234TTTTTTTk454sdOOOOOOOsdhd11111111hf”進(jìn)行切割。

分析:這個(gè)字符串不再像我們之前做過的字符串,他比較特殊,我們之前的疊詞都是一樣的字符,而這個(gè)疊詞中的字符都不相同,如果按照我們之前去切割是不能夠?qū)崿F(xiàn)的,那么我們該如何去切割已知的字符串呢?
我們需要借助正則中的組來完成。

正則中組的概念:
組:把已經(jīng)存在的一個(gè)正則規(guī)則使用小括號封裝起來,當(dāng)在正則表達(dá)式中的其他位置上需要使用
已經(jīng)存在的正則規(guī)則的時(shí)候,這時(shí)沒有必要再書寫重復(fù)的規(guī)則,而直接去引用被封裝好的正則規(guī)則。

例如:"([a-z_A-Z])bc[a-z_A-Z]"

上述正則表達(dá)式:在第一位和第四位上是相同的正則規(guī)則,同一正則表達(dá)式中不同位置上存在了相同規(guī)則的正則,在書寫上重復(fù)沒有必要。我們可以在正則表達(dá)式中的第一個(gè)位置上把[a-z_A-Z] 這個(gè)規(guī)則進(jìn)行封裝到一個(gè)組中。然后在正則的第四位上需要使用和第一位上相同的規(guī)則即可。 這時(shí)可以在第四位上引用這個(gè)被封裝好的組。

在正則中一旦把某個(gè)規(guī)則使用小括號封裝成組之后,由于我們只能使用小括號進(jìn)行組的封裝,而無法給組起名,這時(shí)會自動(dòng)的給這些組進(jìn)行編號,組的編號從1開始,一個(gè)小括號就是一組。

       如果在當(dāng)前分組的這個(gè)正則表達(dá)式中引用已經(jīng)存在的組,需要使用\\組的編號
           例如:"([a-z_A-Z])bc\\1"

需求:使用String類中的split函數(shù)根據(jù)正則表達(dá)式規(guī)則,以疊詞對已知的字符串進(jìn)行切割。(練習(xí)正則表達(dá)式中的組的概念)
1)在RegexDemo2類中定義一個(gè)method_3函數(shù);
2)在method_3函數(shù)中定義一個(gè)字符串str,并賦值為
”sfljs####lfj234TTTTTTTk454sdOOOOOOOsdhd11111111hf”;
3)定義一個(gè)正則表達(dá)式規(guī)則:regex=”(.)\1+”;
4)使用定義好的字符串str調(diào)用split()函數(shù)對正則表達(dá)式進(jìn)行切割;
5)遍歷切割后的數(shù)組;


8.png

需求:電子郵箱匹配的練習(xí);
分析:
1)電子郵箱的@符號是固定的,前面是用戶名,后面是一般公司的域名信息;
2)用戶名可以是數(shù)字 字母 下劃線;
3)公司域名可以是數(shù)字 字母;
步驟:
1)定義RegexDemo3類;
2)在這個(gè)類中定義一個(gè)字符串email,并賦值為”heixuanfeng@163.com”;
3)定義一個(gè)正則表達(dá)式規(guī)則:
regex=”[0-9a-zA-Z_]+@[0-9a-zA-Z]+(\.[a-zA-Z]+){1,3}”;
4)使用字符串對象email調(diào)用String類中的matches函數(shù),regex作為正則表達(dá)式規(guī)則,并打印結(jié)果;

package xuexi.a_regex_demo;
public class RegexDemo3 {
    public static void main(String[] args) {
        //定義一個(gè)字符串
        String str="heixuanfeng@163.com.cn";
        //定義一個(gè)正則表達(dá)式來驗(yàn)證郵箱
        //(\\.[a-zA-Z]+){1,3}表示.com.cn可以出現(xiàn)1到3次
        String regex="\\w+@[0-9a-zA-Z]+(\\.[a-zA-Z]+){1,3}";
        System.out.println(str.matches(regex));
    }
}

1.4.4、替換

9.png

案例1:替換的簡單應(yīng)用
需求:
1)定義一個(gè)RegexDemo4類,在這個(gè)類中定義一個(gè)main函數(shù);
2)在main函數(shù)中定義一個(gè)字符串str,并賦值為hello world;
3)使用str字符串對象調(diào)用String類中的replaceAll()函數(shù)將字符串中的l替換為i,并重新生成一個(gè)字符串,并打印;

10.png

案例2:把字符串中的所有#號變?yōu)?號,最后變成一個(gè)-
需求:
1)在RegexDemo4類中定義一個(gè)method_2函數(shù);
2)在method_2函數(shù)中定義一個(gè)字符串str,并賦值為
“sdhf#jksdhf1232###j45k45dsh54######65f765j#######7kd”;
3)使用str字符串對象調(diào)用String類中的replaceAll()函數(shù)將字符串中所有的#替換為-,并重新生成一個(gè)字符串,并打印;

11.png

案例3:把字符串中的多個(gè)相同字符,替換成一個(gè)字符
原字符串:“abc###nbaAAAAAAsh000000xuexi#####cbaXXXXXXcom”
替換后:” abc#nbaAsh0xuexi#cbaXcom
說明:
前面學(xué)習(xí)了在一個(gè)正則表達(dá)中使用前面已經(jīng)封裝的正則規(guī)則,使用\組號引用
如果需要在其他地方引用正則中的組,這里需要使用 $組號。
需求:
1)在RegexDemo4類中定義一個(gè)method_3函數(shù);
2)在method_3函數(shù)中定義一個(gè)字符串str,并賦值為
“abc###nbaAAAAAAsh000000xuexi#####cbaXXXXXXcom”;
3)使用str字符串對象調(diào)用String類中的replaceAll()函數(shù)將字符串中所有的多個(gè)相同的字符替換成一個(gè)字符,并重新生成一個(gè)字符串,并打印;

12.png

案例4:隱藏手機(jī)號碼中間4位 150****8888

需求:
1)在RegexDemo4類中定義一個(gè)method_4函數(shù);

  1. 在method_4函數(shù)中定義一個(gè)字符串str,并賦值為”15066668888”;
    3)把正則表達(dá)式分為三組,第二組使用****替換,使用str字符串對象調(diào)用String類中的replaceAll()函數(shù)將字符串中的中間四位手機(jī)號替換成****,并重新生成一個(gè)字符串,并打印;


    13.png

1.4.5、獲取

需求:案例:獲取字符串中的所有手機(jī)號碼
“shshska13966668888hdjd13966668888iaj”
正則的獲取功能指的是從一個(gè)字符串中截取出來我們需要的子串。
需要學(xué)習(xí)2個(gè)對象:
1、正則表達(dá)式對象
2、匹配器對象
正則表達(dá)式對象:正則表達(dá)式是計(jì)算機(jī)語言中存在一類具備特定功能的表達(dá)式,那么Java對這類表達(dá)式使用類的描述和封裝。
正則表達(dá)式是在java中存在的一種規(guī)則,而java語言對于存在的事物,都會使用類來描述。在java.util.regex包中存在一個(gè)用來描述正則表達(dá)式的類:


14.png

通過查閱API,可以獲得:
1)Pattern類是最終的類,不能被繼承;
2)Pattern類是java中正則表達(dá)式的實(shí)例對象,而我們書寫好的一個(gè)正則表達(dá)式,被封裝成Pattern的對象之后,這時(shí)我們就可以通過對象的方式來操作正則表達(dá)式;
3)Pattern類沒有構(gòu)造函數(shù),我們不能直接new這個(gè)類的對象。一般不能new對象的類,都會在這個(gè)類中給我們提供靜態(tài)的函數(shù),獲取本類的對象。所以需要使用compile()方法獲取Pattern類實(shí)例;
4)先要有Pattern類的實(shí)例(正則表達(dá)式的實(shí)例對象),通過實(shí)例對象創(chuàng)建匹配器對象(Matcher類),最后是使用匹配器對象中的matcher方法來對正則進(jìn)行驗(yàn)證;


15.png

就可以把一個(gè)字符串形式的正則表達(dá)式,變成Pattern對象。
需求:定義一個(gè)手機(jī)號的正則表達(dá)式,使用Pattern類中的compile函數(shù)將定義好的正則表達(dá)式編譯成正則對象。


16.png

說明:經(jīng)過對正則表達(dá)式的編譯,我們就得到了一個(gè)正則對象,這個(gè)對象中封裝的就是那個(gè)正則表達(dá)式。
把正則表達(dá)式編譯成正則對象之后,這時(shí)只有一個(gè)正則對象,是無法和需要匹配或驗(yàn)證的字符串進(jìn)行關(guān)聯(lián)。
這時(shí)必須讓自己的正則對象和需要匹配的字符串通過中間的匹配器進(jìn)行關(guān)聯(lián),然后才能去操作。


17.png

匹配器對象:


18.png

在Pattern類中提供matcher函數(shù),可以讓當(dāng)前的正則對象與需要匹配的字符串進(jìn)行關(guān)聯(lián),然后得到一個(gè)匹配器對象,我們通過這個(gè)匹配器對象就可以去通過正則操作字符串。

案例:獲取字符串中的所有手機(jī)號碼
“shshska13966668888hdjd13966668888iaj”

步驟:
1)定義一個(gè)手機(jī)號碼的正則表達(dá)式regex=”1[34578][0-9]{9}”;
2)使用Pattern類調(diào)用Pattern類中的compile函數(shù)對上述正則表達(dá)式進(jìn)行編譯生成一個(gè)正則對象p;
3)定義一個(gè)字符串str=”sdjfklsdjf13867891234ksdjfuiotk”;
4)使用正則對象p調(diào)用Pattern類matcher函數(shù),str作為字符串,生成一個(gè)匹配器對象matcher;
5)使用匹配器對象matcher調(diào)用Matcher類中的find()函數(shù)去字符串str中查找根據(jù)指定的正則表達(dá)式的結(jié)果,找到手機(jī)號返回結(jié)果true,找不到返回false;
6)由于字符串可以有多個(gè)手機(jī)號,所以使用while循環(huán)去查找,而matcher.find()作為while循環(huán)的循環(huán)條件;
7)使用匹配器對象matcher調(diào)用Matcher類中的group()函數(shù)找出符合正則的子字符串;


19.png

說明:
1)find()表示根據(jù)正則表達(dá)式去字符串中查找,如果找到,則返回true,找不到返回false;
2)group()表示根據(jù)正則表達(dá)式去字符串中找出符合正則的子字符串;

正則對象和匹配器的使用:
1、需要把一個(gè)正則表達(dá)式,通過Pattern類中的compile函數(shù)編譯成正則對象;
2、使用Pattern類中matcher方法讓正則對象和需要操作的字符串產(chǎn)生關(guān)系,得到一個(gè)匹配器對象;
3、使用匹配器中的find進(jìn)行匹配,使用group方法獲取到匹配到的字符串;

正則的功能:
字符串的匹配、切割、替換、獲取
正則的符號:
. 表示任意的字符
() 對已經(jīng)存在的正則進(jìn)行分組 同一正則引入組 \編號 ,不同 $編號
[] 某個(gè)字符串位置上可以出現(xiàn)的字符列表
{}當(dāng)前某個(gè)正則規(guī)則出現(xiàn)的次數(shù)
? 表示當(dāng)前的規(guī)則可以出現(xiàn)零次或一次

  • 表示當(dāng)前的規(guī)則可以出現(xiàn)零次或一次或多次
  • 表示當(dāng)前的規(guī)則可以出現(xiàn)一次或多次
    ^ 行開始
    $ 行結(jié)尾
    \d 數(shù)字字符 [0-9]
    \w 數(shù)字 字母 下劃線[0-9a-zA-Z_]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,802評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內(nèi)容