<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 0,  comments - 5,  trackbacks - 0
    最近要在項目中做HTML解析,本想使用NekoHTML來解析,但看了下NekoHTML有點復雜,故采用了一種便捷,笨的方式來完成項目的要求. 正則表達式此時發(fā)揮了她巨大的威力,為我排憂解難,很快便完成了HTML解析工作.
    在解析期間,研究了很多java正則表達式使用方法,頗得一些經(jīng)驗,不敢獨享,愿與大家共享.
    -
    java正則表達式通過java.util.regex包下的Pattern類與Matcher類實現(xiàn)(建議在閱讀本文時,打開java API文檔,當介紹到哪個方法時,查看java API中的方法說明,效果會更佳).
    Pattern類用于創(chuàng)建一個正則表達式,也可以說創(chuàng)建一個匹配模式,它的構(gòu)造方法是私有的,不可以直接創(chuàng)建,但可以通過Pattern.complie(String regex)簡單工廠方法創(chuàng)建一個正則表達式,
    Java代碼示例:
    Pattern p=Pattern.compile("\\w+");
    p.pattern();//返回 \w+
    -
    pattern() 返回正則表達式的字符串形式,其實就是返回Pattern.complile(String regex)的regex參數(shù)
    -
    1.Pattern.split(CharSequence input)
    Pattern有一個split(CharSequence input)方法,用于分隔字符串,并返回一個String[],我猜String.split(String regex)就是通過Pattern.split(CharSequence input)來實現(xiàn)的.
    Java代碼示例:
    Pattern p=Pattern.compile("\\d+");
    String[] str=p.split("我的QQ是:456456我的電話是:0532214我的郵箱是:aaa@aaa.com");
    -
    結(jié)果:str[0]="我的QQ是:" str[1]="我的電話是:" str[2]="我的郵箱是:aaa@aaa.com"
    -
    2.Pattern.matcher(String regex,CharSequence input)是一個靜態(tài)方法,用于快速匹配字符串,該方法適合用于只匹配一次,且匹配全部字符串.
    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類的構(gòu)造方法也是私有的,不能隨意創(chuàng)建,只能通過Pattern.matcher(CharSequence input)方法得到該類的實例.
    Pattern類只能做一些簡單的匹配操作,要想得到更強更便捷的正則匹配操作,那就需要將Pattern與Matcher一起合作.Matcher類提供了對正則表達式的分組支持,以及對正則表達式的多次匹配支持.
    Java代碼示例:
    Pattern p=Pattern.compile("\\d+");
    Matcher m=p.matcher("22bb23");
    m.pattern();//返回p 也就是返回該Matcher對象是由哪個Pattern對象的創(chuàng)建的
    -
    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+匹配到了整個字符串
    -
    我們現(xiàn)在回頭看一下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()執(zhí)行匹配操作后,就可以利用以上三個方法得到更詳細的信息.
    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,返回第二組匹配到的子字符串
    -
    現(xiàn)在我們使用一下稍微高級點的正則匹配操作,例如有一段文本,里面有很多數(shù)字,而且這些數(shù)字是分開的,我們現(xiàn)在要將文本中所有數(shù)字都取出來,利用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()循環(huán)替換成
    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
    -
    現(xiàn)在大家應該知道,每次執(zhí)行匹配操作后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()的功能是一樣的,只不過是使用方式不一樣.例如我要將某文本中的所有數(shù)字變成*
    使用String完成該要求
    Java代碼示例:
    String str="我的QQ是:456456 我的電話是:0532214 我的郵箱是:aaa123@aaa.com";
    System.out.println(str.replaceAll("\\d","*"));
    ?
    輸出: 我的QQ是:****** 我的電話是:******* 我的郵箱是:aaa***@aaa.com
    ?
    現(xiàn)在我們用Matcher完成該要求
    Java代碼示例:
    Pattern p=Pattern.compile("\\d");
    -Matcher m=p.matcher("我的QQ是:456456 我的電話是:0532214 我的郵箱是:aaa123@aaa.com");
    System.out.println(m.replaceAll("*"));
    ?
    輸出: 我的QQ是:****** 我的電話是:******* 我的郵箱是:aaa***@aaa.com
    ?
    String.replaceAll()應該是調(diào)用了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 我的郵箱是:aaa123@aaa.com");
    StringBuffer sb=new StringBuffer();
    m.find();? //匹配到456456
    m.appendReplacement(sb,"*");? //將456456之前的字符串追加到sb,再將456456替換為*,并追加到sb
    System.out.println(sb.toString());
    m.appendTail(sb);? //將前面替換過的內(nèi)容連接后面未替換過的內(nèi)容,并放入sb
    System.out.println(sb.toString());
    ?
    輸出:
    我的QQ是:*
    我的QQ是:* 我的電話是:0532214 我的郵箱是:aaa123@aaa.com
    ?
    再看一個例子
    Java代碼示例:
    Pattern p=Pattern.compile("\\d+");
    Matcher m=p.matcher("我的QQ是:456456 我的電話是:0532214 我的郵箱是:aaa123@aaa.com");
    StringBuffer sb=new StringBuffer();
    while(m.find()) {
    ??? m.appendReplacement(sb,"*");
    ??? System.out.println(sb.toString());
    }
    m.appendTail(sb);
    System.out.println("使用appendTail()的最終內(nèi)容是:"+sb.toString());
    ?
    輸出:
    我的QQ是:*
    我的QQ是:* 我的電話是:*
    我的QQ是:* 我的電話是:* 我的郵箱是:aaa*
    使用appendTail()的最終內(nèi)容是:我的QQ是:* 我的電話是:* 我的郵箱是:aaa*@aaa.com
    ?
    關(guān)于這兩個方法就介紹到這,如果不明白的話,還需要自己動下手,認真體會一下其內(nèi)涵.
    ?
    -8.Matcher.region (int?start, int?end) / Matcher.regionEnd() / Matcher.regionStart()
    我們在做匹配操作時,默認去匹配的是整個字符串,例如有一字符串"aabbcc",使用"\\d+"去find()時,是從第一個a開始匹配,也就是索引號為0的位置,開始去匹配,當索引號為0的位置沒有匹配到時,就去下一個位置去匹配...直到匹配到子字符串或匹配完最后一個字符索引號才結(jié)束,很顯然"\\d+"不能匹配"aabbcc",當它匹配完最后一個c時,結(jié)束本次匹配,宣告匹配失敗,也就是說它會去匹配完整個字符串,能不能不去匹配完整個字符串呢,答案是可以的.
    region(int start,int end)就是用來設(shè)置此匹配器的區(qū)域限制。
    先來看一個例子.
    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的字符就結(jié)束匹配.
    為什么是11呢,因為content.length()==11
    現(xiàn)在你應該明白了它的作用,來看一個例子.
    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,為什么,請數(shù)一下索引號就知道了.
    ?
    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剛創(chuàng)建出來,為最初狀態(tài)
    m.find();
    m.group();? //返回aaabb
    m.find();
    m.group();? //返回cc
    ?
    Matcher m2=p.matcher(content);? //此時m2剛創(chuàng)建出來,為最初狀態(tài)
    m.find();
    m.group();? //返回aaabb
    m.reset();? //恢復到了最初狀態(tài),此時相當于m2剛創(chuàng)建出來
    m.find();
    m.group();? //返回aaabb,相信大家應該知道了吧
    ?
    ?Matcher.reset(CharSequence?input) 恢復到最初狀態(tài),并將匹配字符串換成input,以后執(zhí)行匹配操作時,就來匹配input,而不匹配原來的字符串了.
    ?
    10.Matcher.toMatchResult ()
    大家查看一下java API 對Matcher類的說明,會發(fā)現(xiàn)它實現(xiàn)了MatchResult 接口,這個接口只有以下幾個方法
    groupCount()?
    group() / group(int i)
    start() /?start(int i)
    end() / end(int i)
    ?
    至于這幾個方法的功能前面已經(jīng)介紹過,現(xiàn)在我們來看一下toMatchResult() 是如何使用的
    Java代碼示例:
    Pattern p=Pattern.compile("\\d+");
    Matcher m=p.matcher("我的QQ是:456456 我的電話是:0532214 我的郵箱是:aaa123@aaa.com");
    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
    ?
    現(xiàn)在你應該知道,toMatchResult()用于保存某次匹配后的信息,待以后再使用.
    方法使用就說到這里,現(xiàn)在再介紹一個實例
    -
    有這樣一個需求,有一個HTML文件,需要將其中的內(nèi)容抽取出來,并不帶HTML標簽,如果使用正則表達式,這是一件很容易的事情. 前提是這個HTML文件只保留了<body></body>標簽以內(nèi)的內(nèi)容.
    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

    posted on 2007-12-15 12:19 crazy 閱讀(576) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 免费jjzz在线播放国产| 中文亚洲AV片不卡在线观看| 四虎影视永久免费观看地址| 一级做a爰全过程免费视频毛片| 国产人在线成免费视频| 特级无码毛片免费视频| 啊灬啊灬别停啊灬用力啊免费看| 中国一级特黄的片子免费| 亚洲免费中文字幕| 久久99国产综合精品免费| 亚洲AV电影院在线观看| 久久综合给合久久国产免费| 亚洲成a∧人片在线观看无码| 卡1卡2卡3卡4卡5免费视频| 国产亚洲精品免费视频播放| 亚洲熟妇久久精品| 亚洲AV一宅男色影视| 久久国产乱子伦精品免费看| 亚洲人成在线观看| 国产三级免费观看| 亚欧免费视频一区二区三区| 中文字幕久无码免费久久| 亚洲色大成网站www永久网站| 国产∨亚洲V天堂无码久久久| 国产免费人成视频在线观看| 成年人网站免费视频| 免费观看一区二区三区| 性色av极品无码专区亚洲 | 国产一级淫片视频免费看| 蜜桃成人无码区免费视频网站| 特a级免费高清黄色片| 丁香五月亚洲综合深深爱| 午夜免费不卡毛片完整版| 日本亚洲色大成网站www久久| 亚洲国产精品乱码一区二区| xvideos亚洲永久网址| 在线免费观看一级毛片| 免费人成在线观看69式小视频| 免费精品一区二区三区第35 | 亚洲色四在线视频观看| 久久精品国产精品亚洲|