正則表達式筆記

1、正則表達式:

        1. 正則表達式其實就是一種規則,有自己特殊的應用,其作用就是針對字符串進行操作

        2. 正則:就是用於操作字符串的一種規則,其中這些規則使用了一些字符表示

 

2、預定義字符類

        .   點 表示任何字符(與行結束符可能匹配也可能不匹配)

        \d 數字:[0-9]

        \D 非數字: [^0-9]

        \s 空白字符:[ \t \n \x0B \f \r]

        \S 非空白字符:[^\s]

        \w 單詞字符:[a-z A-Z _ 0-9]

        \W 非單詞字符:[^\w]

注意:任何預定義字符在沒有加上數量詞之前,都只能匹配一個字符而已。

2.1 預定義字符案例

// . 表示任意字符,匹配任意字符都返回true
        System.out.println(". 匹配任意字符?" + ("a".matches(".")));
        System.out.println();

        //  \d 表示數字0-9其中一位,匹配0-9返回true,其他返回false
        System.out.println("\\d 匹配任意數字[0-9]?" + ("3".matches("\\d")));
        System.out.println();

        //  \D 表示非數字,即非\d [^0-9],只要不是數字0-9即返回true
        System.out.println("\\D 匹配任意非數字字符:?" + ("a".matches("\\D")));
        System.out.println();

        //  \s 表示空白字符 [ \t \n \x0B \f \r ],匹配這些空調字符返回true,其他返回false
        System.out.println("\\s 匹配任意空白字符?" + ("\t".matches("\\s")));
        System.out.println();

        //  \S 表示非空表字符 [^\s]
        System.out.println("\\S 匹配任意非空白字符?" + ("s".matches("\\S")));
        System.out.println();

        //  \w 表示單詞字符:[a-zA-Z_0-9],匹配大小寫a-z,數字0-9,下劃線_,返回true,其他返回false
        System.out.println("\\w 匹配任意單詞字符?" + ("_".matches("\\w")));
        System.out.println();

        //  \W 表示非單詞字符:[^\w]
        System.out.println("\\W 匹配任意非單詞字符:?" + ("#".matches("\\W")));

    執行結果:

. 匹配任意字符?true

\d 匹配任意數字:(匹配一位數字[0-9])?true

\D 匹配任意非數字字符:?true

\s 匹配任意空白字符?true

\S 匹配任意非空白字符?true

\w 匹配任意單詞字符?true

\W 匹配任意非單詞字符:?true

3、Greedy 數量詞

X  ?          一次或一次也沒有(?表示 最多出現一次X字符)
X  *         零次或多次(* 表示 任意次)
X  +         一次或多次(+ 表示 最少出現一次X字符)
X  {n}    恰好n次(出現n次X字符)
X  {n,}       至少n次(最少出現n次X字符)
X  {n,m}   至少n次,最多m次(出現n<=x<=m 次X字符)

3.1 Greedy 數量詞案例:

// X ?: 問號 表示一次或一次也沒有(最多出現一次X字符)
System.out.println("? 表示 最多一次(0次)?" + ("".matches("\\w?")));// true
System.out.println("? 表示 最多一次(1次)?" + ("a".matches("\\w?")));// true
System.out.println("? 表示 最多一次(2次)?" + ("aa".matches("\\w?")));// false
System.out.println();

//  X *: 星號 表示零次或多次(出現任意次數的X字符)
System.out.println("*表示出現 任意次(0次)?" + ("".matches("\\d*")));// true
System.out.println("*表示出現 任意次(1次)?" + ("1".matches("\\d*")));// true
System.out.println("*表示出現 任意次(2次)?" + ("11".matches("\\d*")));// true
System.out.println();

// X +: 加號表示一次或多次(最少出現一次)
System.out.println("+表示出現1次或多次(0次)?" + ("".matches("\\d+")));// false
System.out.println("+表示出現1次或多次(1次)?" + ("1".matches("\\d+")));// true
System.out.println("+表示出現1次或多次(2次)?" + ("11".matches("\\d+")));// true
System.out.println();

// X {n}: {n}大括號裏寫次數,表示正好出現n次X字符
System.out.println("{2} 表示恰好出現2次(1次)?" + "1".matches("\\d{2}"));// false
System.out.println("{2} 表示恰好出現2次(2次)?" + "11".matches("\\d{2}"));// true
System.out.println("{2} 表示恰好出現2次(3次)?" + "111".matches("\\d{2}"));// false
System.out.println();

// X {n,}: 表示至少出現n次X字符,n次或以上爲true,n次以下爲false
System.out.println("{2,} 表示恰好出現2次(1次)?" + "1".matches("\\d{2,}"));// false
System.out.println("{2,} 表示恰好出現2次(2次)?" + "11".matches("\\d{2,}"));// true
System.out.println("{2,} 表示恰好出現2次(3次)?" + "111".matches("\\d{2,}"));// true
System.out.println();

// X {n,m}: 表示最少出現n次,最多出現m次
System.out.println("{2,4} 表示至少出現2次,最多出現4次(1次)?" + ("1".matches("\\d{2,4}")));// false
System.out.println("{2,4} 表示至少出現2次,最多出現4次(2次)?" + ("11".matches("\\d{2,4}")));// true
System.out.println("{2,4} 表示至少出現2次,最多出現4次(3次)?" + ("122".matches("\\d{2,4}")));// true
System.out.println("{2,4} 表示至少出現2次,最多出現4次(4次)?" + ("1333".matches("\\d{2,4}")));// true
System.out.println("{2,4} 表示至少出現2次,最多出現4次(5次)?" + ("14444".matches("\\d{2,4}")));// false
System.out.println();

    執行結果:

? 表示 最多一次(0次)?true
? 表示 最多一次(1次)?true
? 表示 最多一次(2次)?false

* 表示出現 任意次(0次)?true
* 表示出現 任意次(1次)?true
* 表示出現 任意次(2次)?true

+ 表示出現1次或多次(0次)?false
+ 表示出現1次或多次(1次)?true
+ 表示出現1次或多次(2次)?true

{2} 表示恰好出現2次(1次)?false
{2} 表示恰好出現2次(2次)?true
{2} 表示恰好出現2次(3次)?false

{2,} 表示恰好出現2次(1次)?false
{2,} 表示恰好出現2次(2次)?true
{2,} 表示恰好出現2次(3次)?true

{2,4} 表示至少出現2次,最多出現4次(1次)?false
{2,4} 表示至少出現2次,最多出現4次(2次)?true
{2,4} 表示至少出現2次,最多出現4次(3次)?true
{2,4} 表示至少出現2次,最多出現4次(4次)?true
{2,4} 表示至少出現2次,最多出現4次(5次)?false

 

4、範圍表示

    [abc]: 表示 a、b 或 c
    [^abc]: 表示 任何字符,除了 a、b 或 c
    [a-zA-Z]: 表示 a-z 或 A-Z,兩頭的字母包括在內
    [a-d[m-p]]: 表示 a-d 或者 m-p 的並集
    [bcd&&[def]]: 表示bcd與def的交集
    [a-z&&[^bc]]: 表示 a-z,除了 b 和 c:[a或者d-z]
    [a-z&&[^m-p]]: 表示 a-z和 【a-z 除去m-p】的交集,即 a-l 或者 q-z

4.1 範圍表示 案例

// [abc]:表示匹配a、b 或 c其中的一個字符(簡單類)
System.out.println("[abc]表示匹配a或b或c爲true(a)?" + ("a".matches("[abc]")));//true
System.out.println("[abc]表示匹配a或b或c爲true(e)?" + ("e".matches("[abc]")));//false
System.out.println();

// [^abc]:表示匹配任何字符(1個),除了 a、b 或 c(否定)
    System.out.println("[^abc]表示匹配除abc之外的任意一個字符(a)?" + 
("a".matches("[^abc]")));//false
    System.out.println("[^abc]表示匹配除abc之外的任意一個字符(3)?" + 
("3".matches("[^abc]")));//true
    System.out.println();

//[a-zA-Z]:表示匹配 a到z 或 A到Z 中的任意一個字符,兩頭的字母包括在內(範圍)
    System.out.println("[a-zA-Z]表示匹配a-z和A-Z之中的任意一個字符(F)?" + ("F".matches("[a-zA-Z]")));//true
    System.out.println("[a-zA-Z]表示匹配a-z和A-Z之中的任意一個字符(f)?" + ("f".matches("[a-zA-Z]")));//true
    System.out.println("[a-zA-Z]表示匹配a-z和A-Z之中的任意一個字符(3)?" + ("3".matches("[a-zA-Z]")));//false
    System.out.println();

//[a-d[m-p]]:表示 a到d 或 m到p中的任意一個字符(並集)
    System.out.println("[a-d[m-p]]表示匹配a-d或m-p之中的任意一個字符(B)?" + ("B".matches("[a-d[m-p]]")));//false
    System.out.println("[a-d[m-p]]表示匹配a-d或m-p之中的任意一個字符(b)?" + ("b".matches("[a-d[m-p]]")));//true
    System.out.println("[a-d[m-p]]表示匹配a-d或m-p之中的任意一個字符(m)?" + ("m".matches("[a-d[m-p]]")));//true
    System.out.println();

// [bcd&&[def]]: 表示bcd和def的交集,結果是字符d
    System.out.println("[bcd&&[def]]表示abcd和def的交集(即d)(d)?" + 
("d".matches("[bcd&&[def]]")));// true
    System.out.println("[bcd&&[def]]表示abcd和def的交集(即d)(e)?" + 
("e".matches("[bcd&&[def]]")));// false
    System.out.println("[bcd&&[def]]表示abcd和def的交集(即d)(f)?" +
 ("f".matches("[bcd&&[def]]")));// false
    System.out.println();

// [a-z&&[^bc]]	表示a到z 和 【a-z除了b和c】的交集,結果是a或d-z中的一個字符
    System.out.println("[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(a)?" + "a".matches("[a-z&&[^bc]]"));// true
    System.out.println("[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(b)?" + "b".matches("[a-z&&[^bc]]"));// false
    System.out.println("[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(z)?" + "z".matches("[a-z&&[^bc]]"));// true
    System.out.println();

// [a-z&&[^m-p]]:表示 a-z 與【a-z減去m-p】的交集,結果是a-l和q-z中的一個字符
    System.out.println("[a-z&&[^m-p]]表示 a-z 與【a-z減去m-p】的交集(a)?" + "a".matches("[a-z&&[^m-p]]"));// true
    System.out.println("[a-z&&[^m-p]]表示 a-z 與【a-z減去m-p】的交集(m)?" + "m".matches("[a-z&&[^m-p]]"));// false
    System.out.println("[a-z&&[^m-p]]表示 a-z 與【a-z減去m-p】的交集(z)?" + "z".matches("[a-z&&[^m-p]]"));// true
    System.out.println();

執行結果:

[abc]表示匹配a或b或c爲true(a)?true
[abc]表示匹配a或b或c爲true(e)?false

[^abc]表示匹配除abc之外的任意一個字符(a)?false
[^abc]表示匹配除abc之外的任意一個字符(3)?true

[a-zA-Z]表示匹配a-z和A-Z之中的任意一個字符(F)?true
[a-zA-Z]表示匹配a-z和A-Z之中的任意一個字符(f)?true
[a-zA-Z]表示匹配a-z和A-Z之中的任意一個字符(3)?false

[a-d[m-p]]表示匹配a-d或m-p之中的任意一個字符(B)?false
[a-d[m-p]]表示匹配a-d或m-p之中的任意一個字符(b)?true
[a-d[m-p]]表示匹配a-d或m-p之中的任意一個字符(m)?true

[bcd&&[def]]表示abcd和def的交集(即d)(d)?true
[bcd&&[def]]表示abcd和def的交集(即d)(e)?false
[bcd&&[def]]表示abcd和def的交集(即d)(f)?false

[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(a)?true
[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(b)?false
[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(z)?true

[a-z&&[^m-p]]表示 a-z 與【a-z減去m-p】的交集(a)?true
[a-z&&[^m-p]]表示 a-z 與【a-z減去m-p】的交集(m)?false
[a-z&&[^m-p]]表示 a-z 與【a-z減去m-p】的交集(z)?true

注意:正則表達式中 大括號{ n }表示次數,中括號[a-z]表示範圍。

注意:範圍詞裏邊,不管內容有多長,沒有數量詞的配合,只能匹配其中的一個字符。

5、分組()

     爲了提高規則的複用,用()小括號來對正則表達式的字節進行分組,每個括號都有一個編號,編號從1開始。可以通過編號來完成對該規則的調用。注意:需要對編號規則進行轉義,\\1就表示獲取第一組規則,\\2代表獲取第二組規則,以此類推。

5.1 案例

// 需求:將手機號的中間四位使用*號代替
// 第一步,找到手機號,將手機號分組成三部分,前三位是第一組,中間四位是第二組,最後四位是第三組
// 第二步,將手機號的中間4位用 * 號代替
public static void testReplace() {
    String str = "聯繫我:13567012119聯繫我:13567012119聯繫我:13567012119聯繫我:13567012119聯繫我:13567012119聯繫我:13567012119";
    // 使用小括號將正則表達式分爲3組。
    String reg = "(1[34578][0-9])(\\d{4})(\\d{4})";
    // // $1表示匹配到的第1組子表達式,$3表示第三組子表達式。$1,$2,$3這種格式直接寫在正則表達式中是錯誤的,它只是起到一個佔位的作用。
    String s = str.replaceAll(reg, "$1****$3");
    System.out.println("替換後的帖子是:" + s);
}

執行結果:

替換後的帖子是:聯繫我:135****2119聯繫我:135****2119聯繫我:135****2119聯繫我:135****2119聯繫我:135****2119聯繫我:135****2119

6.邊界匹配器

^ 行的開頭
$ 行的結尾
\b 單詞邊界
\B 非單詞邊界
\A 輸入的開頭
\G 上一個匹配的結尾
\Z 輸入的結尾,僅用於最後的結束符(如果有的話)
\z 輸入的結尾

7.正則表達式的四種常見應用

1. 匹配

     常用方法 matches(reg)

2. 切割

    常用方法 split(reg)

3. 替換

    常用方法 replace(reg,replacement) 、replaceAll(reg,replaement)

4. 查找

    此時需要使用正則表達式對象

7.1 正則表達式的常見應用案例:

public static void main(String[] args) {
    // 1.匹配應用
    System.out.println("使用正則表達式匹配手機號:" + matchesPhone("13933395149"));
    System.out.println("使用正則表達式匹配固話:" + matchesTel("0315-7421005"));
    System.out.println();

    // 切割應用
    System.out.println("使用正則表達式按照空格進行切割:" + Arrays.toString(testSplit1("   今 天   大 家   玩  的  開   心  ")));
    System.out.println("使用正則表達式按照重疊詞進行切割:" + Arrays.toString(testSplit2("大家家家家家玩玩的的的的開心心心!!!")));

    // 替換應用
    testReplace1();
    testReplace2();

    // 查找應用
    getWord();;

}

// 需求:正則表達式匹配手機號,第一位是1,第二位345789,後邊全是數字,一共11位
public static String matchesPhone(String phone) {
    String reg = "1[34578]\\d{9}";
    return phone.matches(reg) ? "合法手機號" : "非法手機號";
}

// 需求:正則表達式匹配固話 區號首位是0,長度3-4位,主機號,首位不能是0,長度7-8位
public static String matchesTel(String tel) {
    String reg = "0\\d{2,3}-[1-9]\\d{6,7}";
    return tel.matches(reg) ? "合法固話" : "非法固話";
}

// 按照空格進行切割
public static String[] testSplit1(String string) {
    return string.split(" +");
}

// 根據重疊詞進行切割
public static String[] testSplit2(String string) {
    // 如果正則的內容需要被複用,那麼需要對正則的內容進行分組,分組的目的是 爲了提高正則的複用性。
    return string.split("(.)\\1+(.)\\2+");
}


// 需求:將字符串中的手機號中間4位替換成****號
public static void testReplace1() {
    String str = "聯繫我:13567012119聯繫我:13567012119聯繫我:13567012119聯繫我:13567012119聯繫我:13567012119聯繫我:13567012119";
    String reg = "(1[34578][0-9])(\\d{4})(\\d{4})";
    // $1表示匹配到的第1組子表達式,$3表示第三組子表達式。$1,$2,$3這種格式直接寫在正則表達式中是錯誤的,它只是起到一個佔位的作用
    String s = str.replaceAll(reg, "$1****$3");
    System.out.println("替換後的帖子是:" + s);
}


// 需求:"我我....我...我.要...要要...要學....學學..學.編..編編.編.程.程.程..程",將字符串還原成 "我要學編程"。
// 分析:第一步:先將所有點去掉。 第二步將所有重疊字進行切割並保留一個
public static void testReplace2() {
    String str = "我我....我...我.要...要要...要學....學學..學.編..編編.編.程.程.程..程";
    // 將所有.去掉
    str = str.replaceAll("\\.+", "");
    System.out.println(str);
    // 將重疊字進行疊詞處理,並保留一個
    str = str.replaceAll("(.)\\1+", "$1");
    System.out.println(str);
}

 

8、通用的正則表達式

    手機號: ^1(3[\\d]|4[579]|5[0-3[5-9]]|6[2[5-7]]|7[1-3[5-8]]|8[0-9]|9[0-3[5-9]])\\d{8}$

    郵箱:    ^[0-9a-zA-Z]+([-\\w])+@([\\w]+\\.)+[a-z]{2,}$     

                   或

                  ^[a-z0-9A-Z]+[-|a-z0-9A-Z._]+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-z]{2,}$

           手機號和郵箱的通用表達式有多重寫法,可以根據自己的習慣編寫,比如將 [0-9] 寫成 [\\d],或者將 [0-3[5-9]] 寫成 [0-9&&[^4]],找到規律就好。勤加練習,應付工作上的一般狀況還是很輕鬆的。

 

 

9、正則對象

  1、查找需要使用的對象:
        Pattern:正則對象
        Matcher:匹配器

    2、正則表達式的編譯表示形式。
          指定爲字符串的正則表達式必須首先被編譯爲此類的實例。然後,可將得到的模式用於創建 Matcher 對象,
      依照正則表達式,該對象可以與任意字符序列匹配。執行匹配所涉及的所有狀態都駐留在匹配器中,所以多個匹配器可以共享同一模式。
          因此,典型的調用順序是
                 Pattern p = Pattern.compile("a*b");
                 Matcher m = p.matcher("aaaaab");
                 boolean b = m.matches();

    3、匹配器要使用的方法
        find():通知匹配器去匹配字符串,查找符合規則的子串。如果能查找到符合規則的子字符串,返回true,否則返回false
        group():獲取符合規則的子串

        注意:使用group方法之前,一定要使用find方法去查找符合規則的字符串,否則報錯。

9.1 案例

使用正則對象查找符合正則表達式規則的內容:需求 在字符串中查找由三個字母組成的單詞

    // 需求:在字符串中獲取由三個字母組成的單詞
    public static void getWord() {
        String str = "da jia hao , ming tian bu fang jia , xie xie !";
        String reg = "\\b[a-zA-Z]{3}\\b";

        // 首先要把字符串的正則編譯成Pattern正則對象,\b表示單詞的邊界
        Pattern pattern = Pattern.compile(reg);

        // 使用正則對象匹配字符串,用於產生一個Matcher 匹配器對象
        Matcher matcher = pattern.matcher(str);

        // matcher.find():判斷字符串中是否存在符合正則表達式的內容
        // matcher.group():獲取符合正則規則的字符串內容
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發佈了28 篇原創文章 · 獲贊 12 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章