本篇是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 Regex Limit Result : 2 { "boo", "and:foo" }
: 5 { "boo", "and", "foo" }
: -2 { "boo", "and", "foo" }
o 5 { "b", "", ":and:f", "", "" }
o -2 { "b", "", ":and:f", "", "" }
o 0 { "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序列正則表達式構造列表
字符
- x --- 字符x
- \\ --- 反斜槓
- \t --- 制符表
- \n --- 換行符
- \r --- 回車
- \f --- 換頁
- \e --- 轉義
字符類
- . --- dot,點,可以匹配任意一個字符
- [abc] --- 包含a,b,c的任何字符,和a|b|c功能相同
- [^abc] --- 1的否定
- [a-zA-Z] --- a-z或A-Z的任何字符
[a-d[m-p]] --- 相當於[a-dm-p]
- f
- \s --- 空白符,就是在屏幕上顯示空白的符號(空格,tab,換行,換頁,回車)
- \S --- 非空白符,相當於[^\S]
- \d --- 數字0-9,相當於[0-9]
- \D --- 8的否定
- \w --- 詞符相當於[a-zA-Z0-9]
- \W --- 11的否定
邏輯操作符
- XY --- Y在X後面
- X|Y --- X或Y
- (X)
邊界匹配符
- ^ --- 一行的起始
- $ --- 一行的結束
- \b --- 詞的邊界
- \B --- 非詞的邊界
- \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次 |