詳解Java正規表示式中Pattern類和Matcher類

NO IMAGE

前言

本文將介紹Java正規表示式中的Pattern類與Matcher類。首先我們要清楚指定為字串的正規表示式必須首先被編譯為pattern類的例項。因此如何更好的瞭解這兩個類,是程式設計人員必須知道的。

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

一、捕獲組的概念

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


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

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

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

二、詳解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)

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我的郵箱是:[email protected]"); 

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

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)

說了這麼多,終於輪到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 我的郵箱是:[email protected]"); 
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時,才可以使用.

總結

以上就這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對指令碼之家的支援。

您可能感興趣的文章:

JAVA正規表示式 Pattern和MatcherJava 正規表示式詳解Java 正規表示式學習總結和一些小例子java中 利用正規表示式提取( )內內容java正規表示式提取數字的方法例項java正規表示式驗證郵箱、電話號碼示例Java/Js下使用正規表示式匹配巢狀Html標籤收集的一些常用java正規表示式Java 正規表示式功能及應用java正規表示式表單驗證類工具類(驗證郵箱、手機號碼、qq號碼等)