[轉] JAVA正則表達式:Pattern類與Matcher類詳解(轉)

java.util.regex是一個用正則表達式所訂製的模式來對字符串進行匹配工做的類庫包。它包括兩個類:Pattern和 Matcher Pattern 一個Pattern是一個正則表達式經編譯後的表現模式。 Matcher 一個Matcher對象是一個狀態機器,它依據Pattern對象作爲匹配模式對字符串展開匹配檢查。 首先一個Pattern實例訂製了一個所用語法與PERL的相似的正則表達式經編譯後的模式,而後一個Matcher實例在這個給定的Pattern實例 的模式控制下進行字符串的匹配工做。
 

如下咱們就分別來看看這兩個類:java

1、捕獲組的概念正則表達式

捕獲組能夠經過從左到右計算其開括號來編號,編號是從1 開始的。例如,在表達式 ((A)(B(C)))中,存在四個這樣的組:spa

1        ((A)(B(C)))
2 (A) 3 (B(C)) 4 (C)

組零始終表明整個表達式。 以 (?) 開頭的組是純的非捕獲 組,它不捕獲文本,也不針對組合計進行計數。

與 組關聯的捕獲輸入始終是與組最近匹配的子序列。若是因爲量化的緣故再次計算了組,則在第二次計算失敗時將保留其之前捕獲的值(若是有的話)例如,將字符 串"aba" 與表達式(a(b)?)+ 相匹配,會將第二組設置爲 "b"。在每一個匹配的開頭,全部捕獲的輸入都會被丟棄。code



2、詳解Pattern類和Matcher類

java正則表達式經過java.util.regex包下的Pattern類與Matcher類實現(建議在閱讀本文時,打開java API文檔,當介紹到哪一個方法時,查看java API中的方法說明,效果會更佳). 
Pattern類用於建立一個正則表達式,也能夠說建立一個匹配模式,它的構造方法是私有的,不能夠直接建立,但能夠經過Pattern.complie(String regex)簡單工廠方法建立一個正則表達式, 
Java代碼示例: 對象

Pattern p=Pattern.compile("\\w+"); 
p.pattern();//返回 \w+ 

pattern() 返回正則表達式的字符串形式,其實就是返回Pattern.complile(String regex)的regex參數

1.Pattern.split(CharSequence input)blog

Pattern有一個split(CharSequence input)方法,用於分隔字符串,並返回一個String[],我猜String.split(String regex)就是經過Pattern.split(CharSequence input)來實現的. 
Java代碼示例: 索引

Pattern p=Pattern.compile("\\d+"); 
String[] str=p.split("個人QQ是:456456個人電話是:0532214個人郵箱是:aaa@aaa.com"); 

結果:str[0]="個人QQ是:" str[1]="個人電話是:" str[2]="個人郵箱是:aaa@aaa.com" 

2.Pattern.matcher(String regex,CharSequence input)是一個靜態方法,用於快速匹配字符串,該方法適合用於只匹配一次,且匹配所有字符串.
文檔

 

Java代碼示例: 字符串

Pattern.matches("\\d+","2223");//返回true Pattern.matches("\\d+","2223aa");//返回false,須要匹配到全部字符串才能返回true,這裏aa不能匹配到 Pattern.matches("\\d+","22bb23");//返回false,須要匹配到全部字符串才能返回true,這裏bb不能匹配到 

 

3.Pattern.matcher(CharSequence input)input

說了這麼多,終於輪到Matcher類登場了,Pattern.matcher(CharSequence input)返回一個Matcher對象.
Matcher類的構造方法也是私有的,不能隨意建立,只能經過Pattern.matcher(CharSequence input)方法獲得該類的實例. 
Pattern類只能作一些簡單的匹配操做,要想獲得更強更便捷的正則匹配操做,那就須要將Pattern與Matcher一塊兒合做.Matcher類提供了對正則表達式的分組支持,以及對正則表達式的屢次匹配支持. 
Java代碼示例: 

Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); m.pattern();//返回p 也就是返回該Matcher對象是由哪一個Pattern對象的建立的 

4.Matcher.matches()/ Matcher.lookingAt()/ Matcher.find()

Matcher類提供三個匹配操做方法,三個方法均返回boolean類型,當匹配到時返回true,沒匹配到則返回false 
matches()對整個字符串進行匹配,只有整個字符串都匹配了才返回true 
Java代碼示例: 

Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); m.matches();//返回false,由於bb不能被\d+匹配,致使整個字符串匹配未成功. Matcher m2=p.matcher("2223"); m2.matches();//返回true,由於\d+匹配到了整個字符串

咱們如今回頭看一下Pattern.matcher(String regex,CharSequence input),它與下面這段代碼等價 
Pattern.compile(regex).matcher(input).matches() 

lookingAt()對前面的字符串進行匹配,只有匹配到的字符串在最前面才返回true 
Java代碼示例: 

Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); m.lookingAt();//返回true,由於\d+匹配到了前面的22 Matcher m2=p.matcher("aa2223"); m2.lookingAt();//返回false,由於\d+不能匹配前面的aa 

find()對字符串進行匹配,匹配到的字符串能夠在任何位置. 
Java代碼示例: 

複製代碼
Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); m.find();//返回true Matcher m2=p.matcher("aa2223"); m2.find();//返回true Matcher m3=p.matcher("aa2223bb"); m3.find();//返回true Matcher m4=p.matcher("aabb"); m4.find();//返回false 
複製代碼

 

5.Mathcer.start()/ Matcher.end()/ Matcher.group()

當使用matches(),lookingAt(),find()執行匹配操做後,就能夠利用以上三個方法獲得更詳細的信息. 
start()返回匹配到的子字符串在字符串中的索引位置. 
end()返回匹配到的子字符串的最後一個字符在字符串中的索引位置. 
group()返回匹配到的子字符串 
Java代碼示例: 

複製代碼
Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("aaa2223bb"); m.find();//匹配2223 m.start();//返回3 m.end();//返回7,返回的是2223後的索引號 m.group();//返回2223  Mathcer m2=m.matcher("2223bb"); m.lookingAt(); //匹配2223 m.start(); //返回0,因爲lookingAt()只能匹配前面的字符串,因此當使用lookingAt()匹配時,start()方法老是返回0 m.end(); //返回4 m.group(); //返回2223  Matcher m3=m.matcher("2223bb"); m.matches(); //匹配整個字符串 m.start(); //返回0,緣由相信你們也清楚了 m.end(); //返回6,緣由相信你們也清楚了,由於matches()須要匹配全部字符串 m.group(); //返回2223bb 
複製代碼

說了這麼多,相信你們都明白了以上幾個方法的使用,該說說正則表達式的分組在java中是怎麼使用的. 
start(),end(),group()均有一個重載方法它們是start(int i),end(int i),group(int i)專用於分組操做,Mathcer類還有一個groupCount()用於返回有多少組. 
Java代碼示例: 

複製代碼
Pattern p=Pattern.compile("([a-z]+)(\\d+)"); 
Matcher m=p.matcher("aaa2223bb"); m.find(); //匹配aaa2223 m.groupCount(); //返回2,由於有2組 m.start(1); //返回0 返回第一組匹配到的子字符串在字符串中的索引號 m.start(2); //返回3 m.end(1); //返回3 返回第一組匹配到的子字符串的最後一個字符在字符串中的索引位置. m.end(2); //返回7 m.group(1); //返回aaa,返回第一組匹配到的子字符串 m.group(2); //返回2223,返回第二組匹配到的子字符串 
複製代碼

如今咱們使用一下稍微高級點的正則匹配操做,例若有一段文本,裏面有不少數字,並且這些數字是分開的,咱們如今要將文本中全部數字都取出來,利用java的正則操做是那麼的簡單. 
Java代碼示例: 

Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("個人QQ是:456456 個人電話是:0532214 個人郵箱是:aaa123@aaa.com"); while(m.find()) { System.out.println(m.group()); } 

輸出: 

456456 
0532214 
123 

 

如將以上while()循環替換成 

while(m.find()) { System.out.println(m.group()); System.out.print("start:"+m.start()); System.out.println(" end:"+m.end()); } 

則輸出: 

456456 
start:6 end:12 
0532214 start:19 end:26 123 start:36 end:39 

如今你們應該知道,每次執行匹配操做後start(),end(),group()三個方法的值都會改變,改變成匹配到的子字符串的信息,以及它們的重載方法,也會改變成相應的信息. 注 意:只有當匹配操做成功,纔可使用start(),end(),group()三個方法,不然會拋出 java.lang.IllegalStateException,也就是當matches(),lookingAt(),find()其中任意一個方法 返回true時,纔可使用.

相關文章
相關標籤/搜索