1. 程式人生 > >Java中使用正則表示式

Java中使用正則表示式

最近要在專案中做HTML解析,本想使用NekoHTML來解析,但看了下NekoHTML有點複雜,故採用了一種便捷,笨的方式來完成專案的要求. 正則表示式此時發揮了她巨大的威力,為我排憂解難,很快便完成了HTML解析工作. 在解析期間,研究了很多java正則表示式使用方法,頗得一些經驗,不敢獨享,願與大家共享. ­ 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 

參考資料:
java.util.regex的API文件
陳廣佳的JAVA正則表示式--Pattern和Matcher

相關推薦

java表示式的瞭解與實踐記錄

Pattern pattern = Pattern.compile("^\\S+/q/"); Matcher matcher = pattern.matcher(resultString); String qrcode=""; while(matcher.find()){ String path

Java表示式相關類Pattern和Matcher的使用

在Java中,java.util.regex包定義了正則表示式使用到的相關類,其中最主要的兩個類為:Pattern、Matcher:   Pattern 編譯正則表示式後建立一個匹配模式;   Matcher 使用Pattern例項提供的正則表示式對目標字串進行匹

Java 表示式

字元類: [abc] a、b 或 c [^abc] 任何字元,除了abc [a-zA-Z] a 到 z 或 A 到 Z ,兩頭的字母包括在內 [0-9] 0到9 的字元都包括 預定義字元類: . 任何字元 \d 數字:[0-9] 示例:判斷手機號的規則: String regex = “

1000行程式碼徒手寫表示式引擎【1】--JAVA表示式的使用

簡介: 本文是系列部落格的第一篇,主要講解和分析正則表示式規則以及JAVA中原生正則表示式引擎的使用。在後續的文章中會涉及基於NFA的正則表示式引擎內部的工作原理,並在此基礎上用1000行左右的JAVA程式碼,實現一個支援常用功能的正則表示式引擎。它支援貪婪匹配和懶惰匹配;支援零寬度字元(如“\b”, “\B

Java表示式匹配的語法規則

, package com.fsti.icop.util.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class RegExpValidatorUt

java表示式驗證日期

/** *正則表示式驗證日期格式     包括潤二月 **/ // public static void main(String[] args) { //  Pattern p = Pattern //      .compile("^((\\d{2}(([02468][

JAVA表示式的二次轉義

需求:格式化金額,替換伺服器返回的格式化字串中的”{0}”為金額 public class Test { public static void main(String[] args) { String unformattedMoney

Java表示式去除html標籤

    注:這是Java正則表示式去除html標籤方法。     private static final String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定義sc

java表示式工具類:Pattern和Macher

原地址 java.util.regex是一個用正則表示式所訂製的模式來對字串進行匹配工作的類庫包。 1.簡介: java.util.regex是一個用正則表示式所訂製的模式來對字串進行匹配工作的類庫包。 它包括兩個類:Pattern和Matcher

java表示式運用例項(用String類的matches方法演示)

java中正則表示式運用例項(參看java中正則表示式運用詳解): 測試程式碼  package test;   /**    * 在String的matches()方法,split()方法中使用正則表示式.    * @author fhd001    */   pu

Java表示式的分割案例

import java.util.Scanner; public class SplitDemo {/**正則表示式的分割案例:*  在鍵盤錄入一個年齡,判斷是不是按照你要求的年齡段。* @param args*/public static void main(String

JAVA表示式總結

下表顯示了正則表示式的語法: 表 1.1 正則表示式語法 元字元 說明 . 匹配任何單個字元。例如正則表示式“b.g”能匹配如下字串:“big”、“bug”、“b g”,但是不匹配“buug”。  $ 匹配行結束符。例如正則表示式“EJB$”能夠匹配字串“I like EJB”的末尾,但是不

Java表示式常用方法彙總

眾所周知,在程式開發中,難免會遇到需要匹配、查詢、替換、判斷字串的情況發生,而這些情況有時又比較複雜,如果用純編碼方式解決,往往會浪費程式設計師的時間及精力。因此,學習及使用正則表示式,便成了解決這一矛盾的主要手段。 大 家都知道,正則表示式是一種可以用於模式匹配和替換的規

java使用表示式從一長串字元獲取一段特徵字串

只能說String工具類太強大,導致一直以來,幾乎沒怎麼用到過正則表示式,現在突然要用到,參考正則表示式語法,摸索一上午才搞出來。記錄分享一下,以免忘記 從一長串字元中,截取出邀請碼,我想很多人都遇到過。 String s = "邀請您加入隨心購,自動搜尋淘寶天貓優惠券!先領券,再購

java利用表示式提取字串的整數和小數部分

最近開發遇到一個新的東西,就是前端傳過來一個字串,需要將裡面的數字提取出來,倒騰了一天,最後還是沒有倒騰出來,最後還是借鑑大佬的方法。記錄一下。 首先是前端傳來的字串“小明通過掃碼向你付款100000.566元”其中暱稱和金額不是固定的,其他是固定的。 於是便考慮使用“通過掃碼向你付

java 利用表示式去處字串的所有空格

轉載自xcmercy的部落格 目標 去除字串中所有的空白字元,包括空格、製表符、回車符等所有空白字元 思路 根據字串長度,利用迴圈遍歷字串此方法太笨拙。這裡利用正則表示式,匹配所有的空白字元,然後將匹配到的空白字元替換為 “” 空串即可。 程式碼 private St

java中用表示式獲取一個指定的子字元在字串出現的指定次數的下標索引,並且進行字串分割

在開發中遇到這樣的一個報文: 00000123000003RQ0 ################ 000003 <tellerLvl0>0</><brc>3004</><fPIflag>0</><

java-使用表示式擷取字串的時間資訊

package com.yr.method; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Aut

java獲取表示式匹配結果的部分內容

在用正則表示式在html程式碼中找到相應標籤後通過分組的方法可以獲取整個匹配內容中的你想要的內容Pattern compile1=Pattern.compile("(<div class=\"channel-detail movie-item-title\" title

1000行代碼徒手寫表達式引擎【1】--JAVA表達式的使用

基礎上 unicode 要求 [1] 分配 find 通過 images char 簡介: 本文是系列博客的第一篇,主要講解和分析正則表達式規則以及JAVA中原生正則表達式引擎的使用。在後續的文章中會涉及基於NFA的正則表達式引擎內部的工作原理,並在此基礎上用1000行左右