欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Java正則表達(dá)式(一)

系統(tǒng) 2076 0

轉(zhuǎn)自 http://fuliang.iteye.com/blog/169946

本系列文章主要是介紹怎樣用java來作正則表達(dá)式的應(yīng)用。

?

正則表達(dá)式在處理文本方面用處非常大,最早像在Perl和awk語言中,提供了這種機(jī)制,Java在Java 2中也增加了正則表達(dá)式這個包java.util.regex。這個包為用戶使用正則表達(dá)式,提供了易用而全面的支持。我的研究方向是web挖掘。從網(wǎng)頁中提取內(nèi)容,處理文本,當(dāng)然需要正則表達(dá)式這個強(qiáng)大的工具了。
一、首先我們看一下怎么使用正則表達(dá)式的一個例子:
A Matcher examines the results of applying a pattern.
我們希望從這句話中找到所有開頭為a的單詞。
當(dāng)然這只是一個簡單的例子,你可以使用String提供的split方法,得到單詞數(shù)組,然后
遍歷各個單詞看是否是否開頭為a
我們現(xiàn)在看看怎么使用正則表達(dá)式來處理這個問題:

Java代碼 復(fù)制代碼
  1. import ?java.util.regex.*; ??
  2. ??
  3. public ? class ?FindA{ ??
  4. ?? public ? static ? void ?main(String?args[]) ??
  5. ?? throws ?Exception{ ??
  6. ??
  7. ????String?candidate?= ??
  8. ????? "A?Matcher?examines?the?results?of?applying?a?pattern." ; ??
  9. ????String?regex?=? "\\ba\\w*\\b" ; ??
  10. ????Pattern?p?=?Pattern.compile(regex); ??
  11. ????Matcher?m?=?p.matcher(candidate); ??
  12. ????String?val?=? null ; ??
  13. ????System.out.println( "INPUT:?" ?+?candidate); ??
  14. ????System.out.println( "REGEX:?" ?+?regex?+ "\r\n" ); ??
  15. ???? while ?(m.find()){ ??
  16. ??????val?=?m.group(); ??
  17. ??????System.out.println( "MATCH:?" ?+?val); ??
  18. ????} ??
  19. ???? if ?(val?==? null )?{ ??
  20. ??????System.out.println( "NO?MATCHES:?" ); ??
  21. ????} ??
  22. ??} ??
  23. }??
    import java.util.regex.*;

public class FindA{
  public static void main(String args[])
  throws Exception{

    String candidate =
     "A Matcher examines the results of applying a pattern.";
    String regex = "\\ba\\w*\\b";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(candidate);
    String val = null;
    System.out.println("INPUT: " + candidate);
    System.out.println("REGEX: " + regex +"\r\n");
    while (m.find()){
      val = m.group();
      System.out.println("MATCH: " + val);
    }
    if (val == null) {
      System.out.println("NO MATCHES: ");
    }
  }
}

  


從這個例子我們可以看到正則表達(dá)式涉及到的兩個類Matcher和Pattern,我們以后會專門討論著連個類。現(xiàn)在主要看看使用正則表達(dá)式的流程:
首先使用 Pattern的一個靜態(tài)的方法compile來創(chuàng)建Pattern對象,

Java代碼 復(fù)制代碼
  1. Pattern?p?=?Pattern.compile(regex);??
    Pattern p = Pattern.compile(regex);

  


然后調(diào)用Pattern的方法matcher

Java代碼 復(fù)制代碼
  1. Matcher?m?=?p.matcher(candidate);??
     Matcher m = p.matcher(candidate);

  


得到了Matcher對象,Matcher對象保存了許多匹配信息,然后可以通過find()方法
查找匹配的部分,如果有匹配的部分,返回真,使用m.group方法得到匹配的各組值,
否則find返回false.
當(dāng)然這只是一般的過程,還有許多更細(xì)的方法,在以后會陸續(xù)的總結(jié),下面我們看一下

Java代碼 復(fù)制代碼
  1. String?regex?=? "\\ba\\w*\\b" ;??
    String regex = "\\ba\\w*\\b";

  


這個就是一個正則表達(dá)式,b,w,*都是正則表達(dá)式的meta character原字符,
\b表示單詞的邊界,w表示任意的可構(gòu)成單詞的字母數(shù)字,*表示前面的字母(當(dāng)然可以
是更復(fù)雜的組之類的了東東)重復(fù)0次或0次以上,a當(dāng)然還是a了。所以這個regex就
匹配單詞開頭為a的單詞了。
二、下面總結(jié)一下基本的正則表達(dá)式的meta character以及它們含義:
.? 匹配任意一個字符 $ 匹配一行的結(jié)尾 ^ 匹配一行的開頭(在[]里面表示否定)
{} 定義了一個范圍  [] 定義了一個字符類 () 定義了一個組
*前面出現(xiàn)0次以上?? + 前面匹配一次以上 ?前面出現(xiàn)0次或一次  
\ 后面的字符不會看作metacharacter? \w 字母數(shù)字下劃線 \W 非字母數(shù)字下劃線
\d 單個數(shù)字 \D單個非數(shù)字 | 或,二者之一 &&與操作符 \b單詞邊界
下面看看幾個簡單的例子:
[abc] a、b 或 c(簡單類)
[^abc] 任何字符,除了a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,兩頭的字母包括在內(nèi)(范圍)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](減去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](減去)
三、java.util.regex提供的操作接口:
java.util.regex包提供了操作正則表達(dá)式的模型,整個模型優(yōu)雅而簡潔,只有三個類:Pattern、Matcher和
PatternSyntaxException。下面將要總結(jié)他們提供的方法,以及如何靈活應(yīng)用來處理文本。

我們還是從Pattern的靜態(tài)工廠方法來擴(kuò)展吧:

Java代碼 復(fù)制代碼
  1. static ?Pattern?compile(String?regex)???
    static Pattern compile(String regex) 

  


將給定的正則表達(dá)式編譯到模式中,并創(chuàng)建Pattern對象,這個方法通常是操作正則表達(dá)式的第一步,從前面那個例子
我們也可以看到整個的流程。
在看看一個重載的compile方法:

Java代碼 復(fù)制代碼
  1. ? ??
  2. static ?Pattern?compile(String?regex,? int ?flags)???
     
static Pattern compile(String regex, int flags) 

  


將給定的正則表達(dá)式編譯到具有給定標(biāo)志的模式中。 這個方法參數(shù)flags提供了一些特殊的選項來用于特殊的處理,
我們下面看看可使用的選項:
UNIX_LINES:這個主要處理UNIX和其他的操作系統(tǒng)在行結(jié)束符不一樣的問題,UNIX使用\n代表一行的終止,而Windows
則使用了\r\n,\n,\r,\u2028或者\(yùn)u0085作為一行的結(jié)束符。
CASE_INSENSITIVE:當(dāng)我們在匹配的時候要忽略字符大小寫時
COMMENTS:允許我們在正則表達(dá)式中使用注釋,例如

Java代碼 復(fù)制代碼
  1. Pattern?p?=Pattern.compile( "A????#matches?uppercase?US-ASCII?char?code?65" ,Pattern.COMMENTS);??
    Pattern p =Pattern.compile("A    #matches uppercase US-ASCII char code 65",Pattern.COMMENTS);

  


MULTILINE:表明要輸入多行,他們有自己的終止字符。

Java代碼 復(fù)制代碼
  1. Pattern?p?=?Pattern.compile( "^" ,?Pattern.MULTILINE);??
    Pattern p = Pattern.compile("^", Pattern.MULTILINE);

  


如果你的輸入的字符串是:This is a sentence.\n So is this..
這樣我們匹配的字符時This中的T和So中的S,如果不使用MULTILINE,則只會匹配T
DOTALL:使用這個選項之后metacharacter .就可以包括一行的終止字符了,如果沒有這個選項,
一行的終止字符,并不會考慮在字符串之內(nèi)的。
使用這個選項會降低效率

Java代碼 復(fù)制代碼
  1. Pattern?p?=?Pattern.compile( "." ,?Pattern.DOTALL);??
    Pattern p = Pattern.compile(".", Pattern.DOTALL);

  


如果我們輸入的是Test\n,則匹配的字符是5個。
UNICODE_CASE:處理UNICODE字符集,使用這個選項會降低效率
CANON_EQ:一個字符的實(shí)際存儲形式是經(jīng)過編碼后的數(shù)字,使用CANON_EQ選項就可以匹配一個字母在各種編碼了。
例如a可以匹配+00E0和U+0061U+0300
使用這個選項會降低效率
我們可以組合以上選項,只要使用|,進(jìn)行按位或操作即可

Java代碼 復(fù)制代碼
  1. Pattern?p?= ??
  2. Pattern.compile( "t?#?a?compound?flag?example" ,Pattern.CASE_INSENSITIVE?|?Pattern.UNICODE_CASE| ??
  3. Pattern.COMMENT);??
    Pattern p =
Pattern.compile("t # a compound flag example",Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE|
Pattern.COMMENT);

  


我們還要注意點(diǎn)的時Java對轉(zhuǎn)譯字符\的處理,例如我們要匹配一個數(shù)字:
我們不能使用:

Java代碼 復(fù)制代碼
  1. Pattern?p?=?Pattern.compile( "\d" );??
    Pattern p = Pattern.compile("\d");

  


而是:

Java代碼 復(fù)制代碼
  1. Pattern?p?=?Pattern.compile( "\\d" );??
    Pattern p = Pattern.compile("\\d");

  


另外如果regex本身形式是錯誤的,compile方法會拋出java.util.regex.PatternSyntaxException異常。
下面我們總結(jié)一下public Matcher matcher(CharSequence input)方法:
當(dāng)我們使用compile操作,創(chuàng)建了Pattern對象之后,我們就可以使用Pattern對象的matcher操作,生成
matcher對象了,Matcher對象包含了許多對匹配結(jié)果集的操作,我們在總結(jié)Matcher對象的時候再說。另外
順便提一下參數(shù)CharSequence,CharBuffer, Segment, String, StringBuffer, StringBuilder 都實(shí)現(xiàn)了
這個接口,所以參數(shù)可以是這些中的任一種類型了。
下面我們看看:

Java代碼 復(fù)制代碼
  1. public ? int ?flags()??
    public int flags()

  


這個方法返回了我們前面可以設(shè)置的并且已經(jīng)設(shè)置的flags選項,我們通過按位與來判斷是否設(shè)置了某個選項:

Java代碼 復(fù)制代碼
  1. int ?flgs?=?myPattern.flags(); ??
  2. boolean ?isUsingCommentFlag?=(?Pattern.COMMENTS?==?(Pattern.COMMENTS?&?flgs))?;??
    int flgs = myPattern.flags();
boolean isUsingCommentFlag =( Pattern.COMMENTS == (Pattern.COMMENTS & flgs)) ;

  


看看一個簡化過程的方法:

Java代碼 復(fù)制代碼
  1. public ? static ? boolean ?matches?(String?regex,CharSequence?input)??
    public static boolean matches (String regex,CharSequence input)

  


這個方法實(shí)際上是:

Java代碼 復(fù)制代碼
  1. Pattern?p?=?Pattern.compile(regex); ??
  2. Matcher?m?=?p.matcher(candidate); ??
  3. m.matches()??
     Pattern p = Pattern.compile(regex);
 Matcher m = p.matcher(candidate);
 m.matches()

  


過程的一個簡化,我們在后面總結(jié)Matcher中的matches方法之后就會理解這個了。
想必我們經(jīng)常使用把字符串提取出token變成字符串?dāng)?shù)組的String中的split方法吧,下面我們看看
類似的一個方法:
public String[] split(CharSequence input)
這個方法提供了強(qiáng)大的功能,因為它可以使用正則表達(dá)式來作為token的分割:

Java代碼 復(fù)制代碼
  1. Pattern?p?=? new ?Pattern.compile( ",|and" ); ??
  2. String?fruits[]?=?p.split( "apple,banana?and?orange" );??
     Pattern p = new Pattern.compile(",|and");
 String fruits[] = p.split("apple,banana and orange");

  


split的一個重載的版本:

Java代碼 復(fù)制代碼
  1. public ?String[]?split(CharSequence?input,? int ?limit)??
    public String[] split(CharSequence input, int limit)

  


它指定了劃分的組數(shù),有以下三種情況:
limit==0
這時候和沒有l(wèi)imit參數(shù)的那個split效果一樣
limit>0
如果你僅僅對前l(fā)imit個感興趣,你可以使用limit:

Java代碼 復(fù)制代碼
  1. String[]?tmp?=?pattern.split( "Hello,?Dolly,?You,?Are,?My,?Favorite" , 3 ); ??
  2. //tmp[0]?is??"Hello", ??
  3. //?tmp[1]?is?"Dolly"; ??
  4. //tmp[2]?is??"You,?Are,?My,?Favorite"; ??
    String[] tmp = pattern.split("Hello, Dolly, You, Are, My, Favorite",3);
//tmp[0] is  "Hello",
// tmp[1] is "Dolly";
//tmp[2] is  "You, Are, My, Favorite";

  


limit<0
會盡可能的劃分所有的組,即使分割符后面是個空字符,也要單獨(dú)生成一個token:""

Java代碼 復(fù)制代碼
  1. Pattern?p?=?Pattern.compile( "," ); ??
  2. String?temp[]?=?p.split( "Hello,Dolly," ,?- 1 ); ??
  3. //temp[]={"Hello","Dolly",""} ??
    Pattern p = Pattern.compile(",");
String temp[] = p.split("Hello,Dolly,", -1);
//temp[]={"Hello","Dolly",""}

  

Java正則表達(dá)式(一)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲一区二区三区在线看 | 久久一区二区视频 | 99青青草 | 国产视频中文字幕 | 久久精品视频在线看99 | 久久精品免费视频观看 | 视频一区二区在线观看 | 久久人人做 | 新久草视频 | 五月婷婷综合激情 | 国产精品久久久999 午夜免费 | 久久99国产精品久久99无号码 | 新神奇四侠免费完整版在线观看 | 天天看天天爽天天摸天天添 | 亚洲成片在线观看12345ba | 在线看av网址 | 韩国日本在线 | 色网站综合 | 国产在线观看av | 99精品视频在线这里只有 | 精品一区二区三区水蜜桃 | 99这里只有精品视频 | 亚洲免费精品视频 | 奇米777四色影视在线看 | 国产精品尤物在线观看一区 | 性xxxx免费观看视频 | 亚洲一区播放 | 亚洲日韩欧洲无码av夜夜摸 | 魔法骑士在线观看免费完整版高清 | 一本一道久久综合狠狠老 | 色妞色视频一区二区三区四区 | 日本三级一区 | 九九热线有精品视频99 | 日韩精品在线一区 | 午夜精品一区二区三区免费视频 | 欧美人成网站 | 亚洲区在线 | 中文字幕在线播放 | 日本啊v在线观看 | 天堂色综合| 日韩欧美精品在线 |