Java -- 正則表達式

本篇是Java編程思想第四版的正則表達式筆記,因爲正則表達式語法很容易忘記,自己整理整理。感覺好多。。還沒寫完

介紹

正則表達式是一種強大而靈活的文本處理工具。通過正則表達式,我們可以構造一個複雜的文本模式,對輸入的字符串進行搜索,一旦找到了匹配這些模式的部分(就是找到了你想要找的字符串),你就可以隨心所欲地處理了。

可以參考JDK文檔的java.util.regex包中的Pattern類,我將其書上列出的放在文章最後面

示例

String類內建的功能

1. matches

引用正則表達式最簡單的途徑就是利用String類的matches方法,但是要注意的是這裏是全字符串匹配

String str1 = "How are you?";
System.out.println(str1.matches("you")); //flase
System.out.println(str1.matches("How are you")); //ture

這裏我一開始就覺得很奇怪,爲什麼不能匹配一個確切的單詞呢,後來發現了一篇博客,才知道原來它會在原來的基礎上自動加上^和$(這兩個都是邊界匹配符表示一行的起始和結束),這樣就變成匹配整個字符串了

如果想要找某個單詞,可以這麼寫

System.out.println("How are you?".matches(".*(are)*"));

點可以匹配任意一個字符,are要括號起來表示一個整體。

數字字符串

System.out.println("+3254".matches("(-|\\+)?\\d+")); //true

這裏\\表示轉義,\\+表示+號字符,不轉移表示重複前面的內容一個或多個,| 表示或者,\d表示就是0-9字符,問號表示重複前面內容的0次或一次,也就是要麼不出現,要麼出現一次。這都是最後面表中的量詞


2. split方法

String類還有一個正則表達式工具,split方法,返回值是一個String數組,它會將字符串從正則表達式匹配的地方切開

for(String temp : "boo:and:foo".split(":")){
    System.out.println(temp + " ");
}
//boo and foo
for(String temp : "boo:and:foo".split("o")){
    System.out.print(temp + " ");
}
b  :and:f

冒號換成\W結果一樣,從第二個看出,匹配的是o,它以o爲分隔符進行分解

split還有一個重載版本,可以指定分割的次數,放上文檔裏面的示例

The string "boo:and:foo", for example, yields the following results with these parameters:

Split example showing regex, limit, and result
RegexLimitResult
:2{ "boo", "and:foo" }
:5{ "boo", "and", "foo" }
:-2{ "boo", "and", "foo" }
o5{ "b", "", ":and:f", "", "" }
o-2{ "b", "", ":and:f", "", "" }
o0{ "b", "", ":and:f" }

Pattern和Matcher

一般來說,比起有限的的String類,我們更願意構造功能強大的正則表達式對象。

你可以通過調用Pattern.compile方法來編譯你的正則表達式,它會生成一個Pattern對象,然後把你想要檢索的字符串傳入Pattern對象的.matcher()方法中,它會生成一個Matcher對象,它有很多功能可以使用。

1. Matcher,public boolean find​()

它會查找與模式匹配的輸入序列的下一個子序列,若之前的find方法調用成功,且Matcher並未被重置,若繼續調用find,則它會從之前匹配的最後一個字符繼續匹配。一旦匹配成功,可以通過start()獲取匹配子串的開始位置,end()獲取結束位置,但是匹配的子串並不包括該索引上的字符,group獲取匹配的字符串,相當於substring(start, end)。

例如寫一個可以匹配1到10個數字和字母的qq郵箱(隨便編的)

查找字符串中所有匹配的子串,輸出起止索引

String str = "[email protected]@qq.com";
Pattern p = Pattern.compile("\\w{1,10}@qq\\.com");
Matcher m = p.matcher(str);
while(m.find()){
    System.out.println(m.start() + " " + m.end()
        + " " + m.group());
}
//0 17 [email protected]
//20 37 [email protected]

輸出匹配的字符索引0-17,不包括17,繼續調用find,他會從上一個查找的最後一個索引開始繼續往後找。

2. Pattern,public static boolean matches​(String regex, CharSequence input)

這個方法和String類的matchers方法很像


()括號的作用

括號可以起到很好的區分作用,比如:(abc)+和abc+表達的意思就不同,後者是匹配ab隨後匹配1個或多個c,前者是匹配1個或多個abc序列

正則表達式構造列表

字符

  1. x --- 字符x
  2. \\ --- 反斜槓
  3. \t --- 制符表
  4. \n --- 換行符
  5. \r --- 回車
  6. \f --- 換頁
  7. \e --- 轉義

字符類

  1. . --- dot,點,可以匹配任意一個字符
  2. [abc] --- 包含a,b,c的任何字符,和a|b|c功能相同
  3. [^abc] --- 1的否定
  4. [a-zA-Z] --- a-z或A-Z的任何字符
  5. [a-d[m-p]] --- 相當於[a-dm-p]
  6. f
  7. \s --- 空白符,就是在屏幕上顯示空白的符號(空格,tab,換行,換頁,回車)
  8. \S --- 非空白符,相當於[^\S]
  9. \d --- 數字0-9,相當於[0-9]
  10. \D --- 8的否定
  11. \w --- 詞符相當於[a-zA-Z0-9]
  12. \W --- 11的否定

邏輯操作符

  1. XY --- Y在X後面
  2. X|Y --- X或Y
  3. (X)

邊界匹配符

  1. ^ --- 一行的起始

  2. $ --- 一行的結束
  3. \b --- 詞的邊界
  4. \B --- 非詞的邊界
  5. \G --- 前一個匹配的結束

量詞

貪婪型

除非有其他的選項設置,貪婪表達式會爲所有可能的符合條件的字符串去匹配。這樣會有一個問題,比如我們的模式只能匹配第一個可能的字符組,但是他還是會繼續匹配。

勉強型

和上面相反,它總是儘可能的匹配滿足模式的所需的最少字符數,懶惰

佔有型

當正則表達式匹配字符串時,它會產生相當多的狀態,以便在匹配失敗的時候可以回溯。而佔有型並不會保存這些中間狀態,因此它可以防止回溯。常用於防止正則表達式失控,因此可以使正則表達式執行起來更有效。(沒有去深究裏面的原理)

貪婪型勉強型佔有型如何匹配
X?X??X?+一個或零個X
X*X*?X*+零個或多個X
X+X+?X++一個或多個X
X{n}X{n}?X{n}+恰好n次X
X{n,}X{n,}?X{n,}+至少n次X
X{n,m}X{n,m}?X{n,m}+至少n次,不超過X次

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