天天看點

JAVA正規表達式:Pattern類與Matcher類詳解

java.util.regex是一個用正規表達式所訂制的模式來對字元串進行比對工作的類庫包。它包括兩個類:Pattern和Matcher Pattern 一個Pattern是一個正規表達式經編譯後的表現模式。 Matcher 一個Matcher對象是一個狀态機器,它依據Pattern對象做為比對模式對字元串展開比對檢查。 首先一個Pattern執行個體訂制了一個所用文法與PERL的類似的正規表達式經編譯後的模式,然後一個Matcher執行個體在這個給定的Pattern執行個體的模式控制下進行字元串的比對工作。

以下我們就分别來看看這兩個類:

一、捕獲組的概念

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

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

與組關聯的捕獲輸入始終是與組最近比對的子序列。如果由于量化的緣故再次計算了組,則在第二次計算失敗時将保留其以前捕獲的值(如果有的話)例如,将字元串"aba" 與表達式(a(b)?)+ 相比對,會将第二組設定為 "b"。在每個比對的開頭,所有捕獲的輸入都會被丢棄。

二、詳解Pattern類和Matcher類

java正規表達式通過java.util.regex包下的Pattern類與Matcher類實作(建議在閱讀本文時,打開java API文檔,當介紹到哪個方法時,檢視java API中的方法說明,效果會更佳). 

Pattern類用于建立一個正規表達式,也可以說建立一個比對模式,它的構造方法是私有的,不可以直接建立,但可以通過Pattern.complie(String regex)簡單工廠方法建立一個正規表達式, 

Java代碼示例: 

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

1.Pattern.split(CharSequence input)

Pattern有一個split(CharSequence input)方法,用于分隔字元串,并傳回一個String[],我猜String.split(String regex)就是通過Pattern.split(CharSequence input)來實作的. 

結果:str[0]="我的QQ是:" str[1]="我的電話是:" str[2]="我的郵箱是:[email protected]

2.Pattern.matcher(String regex,CharSequence input)是一個靜态方法,用于快速比對字元串,該方法适合用于隻比對一次,且比對全部字元串.

3.Pattern.matcher(CharSequence input)

說了這麼多,終于輪到Matcher類登場了,Pattern.matcher(CharSequence input)傳回一個Matcher對象.

Matcher類的構造方法也是私有的,不能随意建立,隻能通過Pattern.matcher(CharSequence input)方法得到該類的執行個體. 

Pattern類隻能做一些簡單的比對操作,要想得到更強更便捷的正則比對操作,那就需要将Pattern與Matcher一起合作.Matcher類提供了對正規表達式的分組支援,以及對正規表達式的多次比對支援. 

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

Matcher類提供三個比對操作方法,三個方法均傳回boolean類型,當比對到時傳回true,沒比對到則傳回false 

matches()對整個字元串進行比對,隻有整個字元串都比對了才傳回true 

我們現在回頭看一下Pattern.matcher(String regex,CharSequence input),它與下面這段代碼等價 

Pattern.compile(regex).matcher(input).matches() 

lookingAt()對前面的字元串進行比對,隻有比對到的字元串在最前面才傳回true 

find()對字元串進行比對,比對到的字元串可以在任何位置. 

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

當使用matches(),lookingAt(),find()執行比對操作後,就可以利用以上三個方法得到更詳細的資訊. 

start()傳回比對到的子字元串在字元串中的索引位置. 

end()傳回比對到的子字元串的最後一個字元在字元串中的索引位置. 

group()傳回比對到的子字元串 

說了這麼多,相信大家都明白了以上幾個方法的使用,該說說正規表達式的分組在java中是怎麼使用的. 

start(),end(),group()均有一個重載方法它們是start(int i),end(int i),group(int i)專用于分組操作,Mathcer類還有一個groupCount()用于傳回有多少組. 

現在我們使用一下稍微進階點的正則比對操作,例如有一段文本,裡面有很多數字,而且這些數字是分開的,我們現在要将文本中所有數字都取出來,利用java的正則操作是那麼的簡單. 

輸出: 

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

則輸出: 

現在大家應該知道,每次執行比對操作後start(),end(),group()三個方法的值都會改變,改變成比對到的子字元串的資訊,以及它們的重載方法,也會改變成相應的資訊. 

注意:隻有當比對操作成功,才可以使用start(),end(),group()三個方法,否則會抛出java.lang.IllegalStateException,也就是當matches(),lookingAt(),find()其中任意一個方法傳回true時,才可以使用.