JAVA筆記之正則表達式

原文地址:https://zhuanlan.zhihu.com/p/59904349

字符匹配符與範圍控制符

  1. . (點) 任意字符
  2. \s (反斜槓加小寫字母s) 空白字符: 回車,製表,空格,換行
  3. \S (反斜槓加大寫字母S) 非空白字符, 除了上面那四個空白字符
  4. \w (反斜槓加小寫字母w) 單詞字符: 小寫字母a-z, 大寫字母A-Z, 數字0-9, 下劃線 _
  5. \W (反斜槓加大寫字母W) 非單詞字符,除了上面提到的那些單詞字符
  6. [ ] (中括號) 範圍字符
    1. [abc] 表示字母abc中的任意一個
    2. [a-z] 表示字母a到z中的任意一個
    3. [^abc] ^ 爲取非, 除了abc, 剩下的全部字符
    4. [abc[def]] 這種寫法爲並集,意爲abcdef中的任意一個
    5. [abc&[bce]] & 表示, 也就是交集。 abc 與上 bce, 最終結果爲bc

 

數量控制符

上面介紹的字符匹配符和範圍控制符,一般是與數量控制符組合使用,才能發揮真正威力。 而數量控制符號,分爲貪婪型,勉強型,和佔有型三種類型,每種類型在不同的場合有不同的用法。

貪婪型

  1. ? 表示1個或0個。換句話說,表示要不然沒有,要不然只有1個
  2. * 表示0個或多個。
  3. + 表示1個或多個。
  4. {n} 表示正好n個
  5. {n,m} 表示n到m個,這是一個左閉右閉區間
  6. {n,} 表示至少n個

 

勉強型

相比於貪婪型,勉強型只是多了一個?:

 

  1. ?? 表示1個或0個。換句話說,表示要不然沒有,要不然只有1個
  2. *? 表示0個或多個。
  3. +? 表示1個或多個。
  4. {n}? 表示正好n個
  5. {n,m}? 表示n到m個,這是一個左閉右閉區間
  6. {n,}? 表示至少n個

佔有型

相比於貪婪型,佔有型多了一個 +

 

  1. ?+ 表示1個或0個。換句話說,表示要不然沒有,要不然只有1個
  2. *+ 表示0個或多個。
  3. ++ 表示1個或多個。
  4. {n}+ 表示正好n個
  5. {n,m}+ 表示n到m個,這是一個左閉右閉區間
  6. {n,}+ 表示至少n個

不同類型的區別

現在詳細分析 貪婪型、勉強型和佔有型的區別, 舉例如下:

        String s = "abcd&"; 			// 目標字符串
        String regular = "\\w+\\w";		// 貪婪型正則
		String regular2 = "\\w+?\\w";		// 勉強型正則
		String regular3 = "\\w++\\w";		// 佔有型正則
        Matcher m = Pattern.compile(regular).matcher(s);
		// 調用方法去匹配字符串
        if(m.find()) {
		   System.out.println(m.group());
		}

分析:

  1. 貪婪型。\w+, 意爲匹配一個或多個單詞字符,對於貪婪型,將盡量多的匹配字符,abcd全部匹配出來,直到遇到特殊字符&,匹配結束,然後用\w 去匹配特殊字符&,發現並不匹配,此時將會回溯,也就是說\w+只匹配abc三位,然後讓最後一個\w去匹配d,最終\\w+\\w匹配出結果abcd.
  2. 勉強型。對於勉強型,會盡量少的匹配字符。既然,+表示一個或多個,那就只匹配一個,所以\w+?最終只匹配出一個a, 然後\w再去匹配一個b,最終匹配結果爲ab。
  3. 佔有型。 佔有型和貪婪型很像,剛開始也會盡量多的匹配字符,但是佔有型沒有回溯機制,遇到不匹配的內容後,將自動停止而不是向前回溯。 所以 \\w++,自動匹配到abcd之後,遇到了&,發現不匹配,然後自動停止了,此時還有一個\w也和&不匹配,所以最終結果匹配失敗,輸出爲空。

位置匹配符

位置匹配符,不匹配任何字符只匹配位置。也就是說,位置匹配符是零寬度的,只匹配位置。

  1. ^ 匹配一行的開始位置
  2. $ 匹配一行的結束位置
  3. \b 匹配單詞邊界。 這裏的單詞指的就是, a-z, 0-9, _, 和\w不同的是,\b匹配的單詞還包括漢字。 單詞邊界匹配,是匹配單詞字符和非單詞字符之間的位置。
  4. \B 匹配非單詞邊界。和\b,剛好相反, \B 匹配單詞與單詞之間的位置,或者非單詞與非單詞之間的位置。
  5. \G 匹配前一個匹配結束時的位置。

 

舉例說明:

String s = "a=124_a=789_a=490"; 	
String regular = "^a=\\d+";

比如說只想把開頭的a=124找出來,而不關心後面的a,此時就可以用位置匹配符。^匹配一行的開始位置,a= 去匹配 a=, \\d+匹配出124, 所以最終可正確匹配出開始位置的a=124

 

還有一類特殊的匹配符,雖然嚴格意義上來說不能算是位置匹配符,但是由於這類匹配符也是零寬度的,所以本文章把這類匹配符歸爲位置匹配符。 這類特殊的匹配符,稱爲零寬度斷言匹配

  1. (?=exp) 零寬度向前匹配
  2. (?<=exp) 零寬度向後匹配
  3. (?!exp) 零寬度向前非匹配
  4. (?<!exp) 零寬度向後非匹配

舉例說明2:

// 目標字符串。 只想取出2前面的abc
                String s = "abc1 abc1 abc2 abc3";
                String regular = "\\w{3}(?=2)";
		Matcher m = Pattern.compile(regular).matcher(s);
                while(m.find()) {
                   System.out.println(m.group());
		}

 

就像是$匹配字符串結尾一樣,(?=2) 也是匹配字符串中爲2的位置,然後再去檢查(?=2)前面的\\w{3} 是否匹配abc, 匹配則輸出結果。 之所以說是零寬度,是因爲(?=2)只是起一個錨點定位作用,此時尾指針指向的不是2後面,而是c後面。

再比如說3:

String s = "aaaaaaaa";
                String regular = "aa(?=aa)";
		Matcher m = Pattern.compile(regular).matcher(s);
                while(m.find()) {
	            System.out.println(m.group());
		}

結果輸出將是: aa aa aa

因爲,第1次匹配,匹配到前4個a,輸出aa; 第2次匹配,是從第2個a後開始向後,而不是第4個a後面,(?=aa) 只標定位置,不佔有寬度; 以此類推,最終結果輸出爲aa aa aa

舉例說明4:

對於零寬度向前匹配,和向後匹配方向相反:

// 目標字符串。 只要求輸出2後面的abc
                String s = "1abc 2abc 3abc";
                String regular = "(?<=2)\\w{3}";
		Matcher m = Pattern.compile(regular).matcher(s);
                while(m.find()) {
			System.out.println(m.group());
		}

 

只要求輸出2後面的abc,那麼就可以用(?<=2)來進行錨點標定,匹配出其後面的字符串。

 

對於(?!exp) 和 (?<!exp) 這兩個非匹配斷言,和匹配斷言正好相反。 (?!exp) 是要求匹配內容的後面,不能有指定的內容; (?<!exp) 要求匹配的前面不能有指定的內容。

 

模式說明符

  1. (?i) 開啓大小寫忽略模式,但是隻適用於ASCII字符
  2. (?u) 開啓utf-8編碼模式
  3. (?m) 開啓多行匹配模式,.不匹配空白字符
  4. (?s) 單行模式,.匹配任意字符,包括空白字符
  5. (?d) 單行模式,.不匹配空白字符

 

舉例說明:

String test2 = "I care not whether I can succeed\n"
		+ "Since in choice of the distance\n"
		+ "I simply travel in wind and rain\n"
		+ "I care not whether I can win love\n"
		+ "Since in deep love with a rose\n"
		+ "I just unbosom myself bravely"; 
String reg = "(?m)\\w{3}$";

在默認情況下,^ 和 $ 只匹配全部字符串的開始與結束位置,但是如果用(?m)開啓多行匹配模式之後, ^ 和 $ 將匹配每一行的開始與結束位置。所以說,上面上面那個舉例正則(?m)\\w{3}$,將會匹配出每一行的最後三個字符。

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