Java中正則表達式的使用

轉載自:http://blog.csdn.net/zhanngle/article/details/1750556

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時,纔可以使用.
6.Matcher.replaceAll(String replacement) / Matcher.replaceFirst(String replacement)
大家應該知道String.replaceAll()和String.replaceFirst()兩個方法的功能,其實它與Matcher.replaceAll()和Matcher.replaceFirst()的功能是一樣的,只不過是使用方式不一樣.例如我要將某文本中的所有數字變成*
使用String完成該要求
Java代碼示例:
String str="我的QQ是:456456 我的電話是:0532214 我的郵箱是:[email protected]";
System.out.println(str.replaceAll("//d","*"));
 
輸出: 我的QQ是:****** 我的電話是:******* 我的郵箱是:aaa***@aaa.com
 
現在我們用Matcher完成該要求
Java代碼示例:
Pattern p=Pattern.compile("//d");
Matcher m=p.matcher("我的QQ是:456456 我的電話是:0532214 我的郵箱是:[email protected]");
System.out.println(m.replaceAll("*"));
 
輸出: 我的QQ是:****** 我的電話是:******* 我的郵箱是:aaa***@aaa.com
 
String.replaceAll()應該是調用了Matcher.replaceAll(),String.replaceAll()與下面這段代碼等價
Pattern.compile(regex).matcher(str).replaceAll(replacement)
 
至於Matcher.replaceFirst()也很簡單,它與String.replaceFirst()功能一樣,我就不多說了.
str.replaceFirst(regex, replacement)與下面這段代碼等價
Pattern.compile(regex).matcher(str).replaceFirst(replacement)
 
7.Matcher.appendReplacement(StringBuffer sb, String replacement) / Matcher.appendTail(StringBuffer sb)
將當前匹配子串替換爲指定字符串,並且將替換後的子串以及其之前到上次匹配子串之後的字符串段添加到一個StringBuffer對象裏,而appendTai­l(StringBuffer sb) 方法則將最後一次匹配工作後剩餘的字符串添加到一個StringBuffer對象裏.看例子:
Java代碼示例:
Pattern p=Pattern.compile("//d+");
Matcher m=p.matcher("我的QQ是:456456 我的電話是:0532214 我的郵箱是:[email protected]");
StringBuffer sb=new StringBuffer();
m.find();  //匹配到456456
m.appendReplacement(sb,"*");  //將456456之前的字符串追加到sb,再將456456替換爲*,並追加到sb
System.out.println(sb.toString());
m.appendTail(sb);  //將前面替換過的內容連接後面未替換過的內容,並放入sb
System.out.println(sb.toString());
 
輸出:
我的QQ是:*
我的QQ是:* 我的電話是:0532214 我的郵箱是:[email protected]
 
再看一個例子
Java代碼示例:
Pattern p=Pattern.compile("//d+");
Matcher m=p.matcher("我的QQ是:456456 我的電話是:0532214 我的郵箱是:[email protected]");
StringBuffer sb=new StringBuffer();
while(m.find()) {
    m.appendReplacement(sb,"*");
    System.out.println(sb.toString());
}
m.appendTail(sb);
System.out.println("使用appendTail()的最終內容是:"+sb.toString());
 
輸出:
我的QQ是:*
我的QQ是:* 我的電話是:*
我的QQ是:* 我的電話是:* 我的郵箱是:aaa*
使用appendTail()的最終內容是:我的QQ是:* 我的電話是:* 我的郵箱是:aaa*@aaa.com
 
關於這兩個方法就介紹到這,如果不明白的話,還需要自己動下手,認真體會一下其內涵.
 
8.Matcher.region(int start, int end) / Matcher.regionEnd() / Matcher.regionStart()
我們在做匹配操作時,默認去匹配的是整個字符串,例如有一字符串"aabbcc",使用"//d+"去find()時,是從第一個a開始匹配,也就是索引號爲0的位置,開始去匹配,當索引號爲0的位置沒有匹配到時,就去下一個位置去匹配...直到匹配到子字符串或匹配完最後一個字符索引號才結束,很顯然"//d+"不能匹配"aabbcc",當它匹配完最後一個c時,結束本次匹配,宣告匹配失敗,也就是說它會去匹配完整個字符串,能不能不去匹配完整個字符串呢,答案是可以的.
region(int start,int end)就是用來設置此匹配器的區域限制。
先來看一個例子.
Java代碼示例:
Pattern p=Pattern.compile("//d+");
String content="aaabb2233cc";
Matcher m=p.matcher(content);
System.out.println(m);
 
輸出: java.util.regex.Matcher[pattern=/d+ region=0,11 lastmatch=]
 
可以看到region=0,11 表示start=0,end=11,更通俗的說就是當去匹配字符串,先從索引號爲0的位置去匹配,如果匹配到了子字符串就返回,如果沒有匹配到則到下一個位置去匹配,一直匹配到索引號爲11-1的字符就結束匹配.
爲什麼是11呢,因爲content.length()==11
現在你應該明白了它的作用,來看一個例子.
Java代碼示例:
Pattern p=Pattern.compile("//d+");
String content="aaabb2233cc";
Matcher m=p.matcher(content);
m.find();  //匹配到2223,返回true
 
Matcher m2=p.matcher(content);
m2.region(0,5);
m2.find();  //返回false,只去匹配索引號0至5-1的字符,沒有匹配到
 
Matcher m3=p.matcher(content);
m2.region(3,8);
m2.find();  //返回true
m2.group();  //返回223,爲什麼,請數一下索引號就知道了.
 
Matcher.regionStart()返回region(int start,int end)中的start值,默認爲0
Matcher.regionEnd()返回region(int start,int end)中的end值,默認爲去匹配字符串的length()值

9.Matcher.reset() / Matcher.reset(CharSequence input)
用於重置匹配器。看示例
Java代碼示例:
Pattern p=Pattern.compile("[a-z]+");
String content="aaabb2233cc";
Matcher m=p.matcher(content);  //此時m剛創建出來,爲最初狀態
m.find();
m.group();  //返回aaabb
m.find();
m.group();  //返回cc
 
Matcher m2=p.matcher(content);  //此時m2剛創建出來,爲最初狀態
m.find();
m.group();  //返回aaabb
m.reset();  //恢復到了最初狀態,此時相當於m2剛創建出來
m.find();
m.group();  //返回aaabb,相信大家應該知道了吧
 
 Matcher.reset(CharSequence input) 恢復到最初狀態,並將匹配字符串換成input,以後執行匹配操作時,就來匹配input,而不匹配原來的字符串了.
 
10.Matcher.toMatchResult()
大家查看一下java API 對Matcher類的說明,會發現它實現了MatchResult 接口,這個接口只有以下幾個方法
groupCount() 
group() / group(int i)
start() / start(int i)
end() / end(int i)
 
至於這幾個方法的功能前面已經介紹過,現在我們來看一下toMatchResult() 是如何使用的
Java代碼示例:
Pattern p=Pattern.compile("//d+");
Matcher m=p.matcher("我的QQ是:456456 我的電話是:0532214 我的郵箱是:[email protected]");
List list=new ArrayList();
while(m.find()) {
    list.add(m.toMatchResult());
}
MatchResult matchResult=null;
Iterator it=list.iterator();
int i=1;
while(it.hasNext()) {
    matchResult=(MatchResult)it.next();
    System.out.print("第"+(i++)+"次匹配到的信息: ");
    System.out.println(matchResult.group()+"/t/t"+matchResult.start()+"/t"+matchResult.end());
}
 
輸出:
第1次匹配到的信息: 456456           6        12
第2次匹配到的信息: 0532214        19      26
第3次匹配到的信息: 123                 36      39
 
現在你應該知道,toMatchResult()用於保存某次匹配後的信息,待以後再使用.
方法使用就說到這裏,現在再介紹一個實例
有這樣一個需求,有一個HTML文件,需要將其中的內容抽取出來,並不帶HTML標籤,如果使用正則表達式,這是一件很容易的事情. 前提是這個HTML文件只保留了<body></body>標籤以內的內容.
Java代碼示例:
String html="<div><font  color='red'>example1</font></div>"; //可以是任何html文件源代碼,但格式一定要正確
Pattern p=Pattern.compile("<[^>]*>");
Matcher m=p.matcher(html);
String result=m.replaceAll("");
System.out.println(result);
輸出:example1 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章