日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > Java正則表達式(超詳細)

Java正則表達式(超詳細)

來源:程序員人生   發布時間:2017-02-20 10:06:57 閱讀次數:3040次


學習Java的同學注意了!!! 
學習進程中遇到甚么問題或想獲得學習資源的話,歡迎加入Java學習交換群,群號碼:183993990  我們1起學Java!


在Sun的Java JDK 1.40版本中,Java自帶了支持正則表達式的包,本文就拋磚引玉地介紹了如何使用java.util.regex包。

  可粗略估計1下,除偶爾用Linux的外,其他Linu x用戶都會遇到正則表達式。正則表達式是個極端強大工具,而且在字符串模式-匹配和字符串模式-替換方面富有彈性。在Unix世界里,正則表達式幾近沒有甚么限制,可肯定的是,它利用非常之廣泛。

  正則表達式的引擎已被許多普通的Unix工具所實現,包括grep,awk,vi和Emacs等。另外,許多使用比較廣泛的腳本語言也支持正則表達式,比如Python,Tcl,JavaScript,和最著名的Perl。

  我很早之前就是個Perl方面的黑客,如果你和我1樣話,你也會非常依賴你手邊的這些強大的text-munging工具。近幾年來,像其他程序開發者1樣,我也愈來愈關注Java的開發。

  Java作為1種開發語言,有許多值得推薦的地方,但是它1直以來沒有自帶對正則表達式的支持。直到最近,借助于第3方的類庫,Java開始支持正則表達式,但這些第3方的類庫都不1致、兼容性差,而且保護代碼起來很糟。這個缺點,對我選擇Java作為重要的開發工具來講,1直是個巨大的顧慮的地方。

  你可以想象,當我知道Sun的Java JDK 1.40版本包括了java.util.regex(1個完全開放、自帶的正則表達式包)時,是多么的高興!很弄笑的說,我花好些時間去發掘這個被隱藏起來的寶石。我非常驚奇的是,Java這樣的1個很大改進(自帶了java.util.regex包)為何不多公然1點呢?!

  最近,Java雙腳都跳進了正則表達式的世界。java.util.regex包在支持正則表達也有它的過人的地方,另外Java也提供詳細的相干說明文檔。使得朦朦朧朧的regex神秘景象也漸漸被扒開。有1些正則表達式的構成(可能最顯著的是,在于糅合了字符類庫)在Perl都找不到。

  在regex包中,包括了兩個類,Pattern(模式類)和Matcher(匹配器類)。Pattern類是用來表達和陳說所要搜索模式的對象,Matcher類是真正影響搜索的對象。另加1個新的例外類,PatternSyntaxException,當遇到不合法的搜索模式時,會拋出例外。

  即便對正則表達式很熟習,你會發現,通過java使用正則表達式也相當簡單。要說明的1點是,對那些被Perl的單行匹配所寵壞的Perl狂酷愛好者來講,在使用java的regex包進行替換操作時,會比他們所之前經常使用的方法費事些。

  本文的局限的地方,它不是1篇正則表達式用法的完全教程。如果讀者要對正則表達進1步了解的話,推薦瀏覽Jeffrey Frieldl的Mastering Regular Expressions,該書由O’Reilly出版社出版。我下面就舉1些例子來教讀者如何使用正則表達式,和如何更簡單地去使用它。

  設計1個簡單的表達式來匹配任何電話號碼數字多是比較復雜的事情,緣由在于電話號碼格式有很多種情況。所有必須選擇1個比較有效的模式。比如:(212) 555⑴212, 212⑸55⑴212和212 555 1212,某些人會認為它們都是等價的。

  首先讓我們構成1個正則表達式。為簡單起見,先構成1個正則表達式來辨認下面格式的電話號碼數字:(nnn)nnn-nnnn。

  第1步,創建1個pattern對象來匹配上面的子字符串。1旦程序運行后,如果需要的話,可讓這個對象1般化。匹配上面格式的正則表達可以這樣構成:(/d{3})/s/d{3}-/d{4},其中/d單字符類型用來匹配從0到9的任何數字,另外{3}重復符號,是個簡便的記號,用來表示有3個連續的數字位,也等效于(/d/d/d)。/s也另外1個比較有用的單字符類型,用來匹配空格,比如Space鍵,tab鍵和換行符。

  是否是很簡單?但是,如果把這個正則表達式的模式用在java程序中,還要做兩件事。對java的解釋器來講,在反斜線字符(/)前的字符有特殊的含義。在java中,與regex有關的包,其實不都能理解和辨認反斜線字符(/),雖然可以試試看。但為避免這1點,即為了讓反斜線字符(/)在模式對象中被完全地傳遞,應當用雙反斜線字符(/)。另外圓括號在正則表達中兩層含義,如果想讓它解釋為字面上意思(即圓括號),也需要在它前面用雙反斜線字符(/)。也就是像下面的1樣:

  //(//d{3}//)//s//d{3}-//d{4}

  現在介紹怎樣在java代碼中實現剛才所講的正則表達式。要記住的事,在用正則表達式的包時,在你所定義的類前需要包括該包,也就是這樣的1行:

  import java.util.regex.*;

  下面的1段代碼實現的功能是,從1個文本文件逐行讀入,并逐行搜索電話號碼數字,1旦找到所匹配的,然后輸出在控制臺。

  BufferedReader in;

  Pattern pattern = Pattern.compile("http://(//d{3}//)//s//d{3}-//d{4}");

  in = new BufferedReader(new FileReader("phone"));

  String s;

  while ((s = in.readLine()) != null)

  {

  Matcher matcher = pattern.matcher(s);

  if (matcher.find())

  {

  System.out.println(matcher.group());

  }

  }

  in.close();

  對那些熟習用Python或Javascript來實現正則表達式的人來講,這段代碼很平常。在Python和Javascript這些語言中,或其他的語言,這些正則表達式1旦明確地編譯過后,你想用到哪里都可以。與Perl的單步匹配相比,看起來多多做了些工作,但這其實不很費事。

  find()方法,就像你所想象的,用來搜索與正則表達式相匹配的任何目標字符串,group()方法,用來返回包括了所匹配文本的字符串。應注意的是,上面的代碼,僅用在每行只能含有1個匹配的電話號碼數字字符串時。可以肯定的說,java的正則表達式包能用在1行含有多個匹配目標時的搜索。本文的原意在于舉1些簡單的例子來激起讀者進1步去學習java自帶的正則表達式包,所以對此就沒有進行深入的探討。

  這相當漂亮吧! 但是很遺憾的是,這僅是個電話號碼匹配器。很明顯,還有兩點可以改進。如果在電話號碼的開頭,即區位號和本地號碼之間可能會有空格。我們也可匹配這些情況,則通過在正則表達式中加入/s?來實現,其中?元字符表示在模式可能有0或1個空格符。

  第2點是,在本地號碼位的前3位和后4位數字間有多是空格符,而不是連字號,更有勝者,或根本就沒有分隔符,就是7位數字連在1起。對這幾種情況,我們可以用(-|)?來解決。這個結構的正則表達式就是轉換器,它能匹配上面所說的幾種情況。在()能含有管道符|時,它能匹配是不是含有空格符或連字符,而尾部的?元字符表示是不是根本沒有分隔符的情況。

  最后,區位號也可能沒有包括在圓括號內,對此可以簡單地在圓括號后附上?元字符,但這不是1個很好的解決方法。由于它也包括了不配對的圓括號,比如"(555" 或 "555)"。相反,我們可以通過另外一種轉換器來逼迫讓電話號碼是不是帶有有圓括號:(/(/d{3}/)|/d{3})。如果我們把上面代碼中的正則表達式用這些改進后的來替換的話,上面的代碼就成了1個非常有用的電話號碼數字匹配器:

  Pattern pattern =

  Pattern.compile("(//(//d{3}//)|//d{3})//s?//d{3}(-|)?//d{4}");

  可以肯定的是,你可以自己試著進1步改進上面的代碼。

  現在看看第2個例子,它是從Friedl的中改編過來的。其功能是用來檢查文本文件中是不是有重復的單詞,這在印刷排版中會常常遇到,一樣也是個語法檢查器的問題。

  匹配單詞,像其他的1樣,也能夠通過好幾種的正則表達式來完成。可能最直接的是/b/w+/b,其優點在于只需用少許的regex元字符。其中/w元字符用來匹配從字母a到u的任何字符。+元字符表示匹配匹配1次或屢次字符,/b元字符是用來講明匹配單詞的邊界,它可以是空格或任何1種不同的標點符號(包括逗號,句號等)。

  現在,我們怎樣來檢查1個給定的單詞是不是被重復了3次?為完成這個任務,需充分利用正則表達式中的所熟知的向后掃描。如前面提到的,圓括號在正則表達式中有幾種不同的用法,1個就是能提供組合類型,組合類型用來保存所匹配的結果或部份匹配的結果(以便后面能用到),即便遇到有相同的模式。在一樣的正則表達中,可能(也通常期望)不止有1個組合類型。在第n個組合類型中匹配結果可以通過向后掃描來獲得到。向后掃描使得搜索重復的單詞非常簡單:/b(/w+)/s+/1/b。

  圓括號構成了1個組合類型,在這個正則表示中它是第1組合類型(也是唯一的1個)。向后掃描/1,指的是任何被/w+所匹配的單詞。我們的正則表達式因此能匹配這樣的單詞,它有1個或多個空格符,后面還跟有1個與此相同的單詞。注意的是,尾部的定位類型(/b)必不可少,它可以避免產生毛病。如果我們想匹配"Paris in the the spring",而不是匹配"Java's regex package is the theme of this article"。根據java現在的格式,則上面的正則表達式就是:Pattern pattern =Pattern.compile("http://b(//w+)//s+//1//b");

  最落后1步的修改是讓我們的匹配器對大小寫敏感。比如,下面的情況:"The the theme of this article is the Java's regex package.",這1點在regex中能非常簡單地實現,即通過使用在Pattern類中預定義的靜態標志CASE_INSENSITIVE :

  Pattern pattern =Pattern.compile("http://b(//w+)//s+//1//b",

  Pattern.CASE_INSENSITIVE);

  有關正則表達式的話題是非常豐富,而且復雜的,用Java來實現也非常廣泛,則需要對regex包進行的完全研究,我們在這里所講的只是冰山1角。即便你對正則表達式比較陌生,使用regex包后會很快發現它強大功能和可伸縮性。如果你是個來自Perl或其他語言王國的老練的正則表達式的黑客,使用過regex包后,你將會安心腸投入到java的世界,而放棄其他的工具,并把java的regex包看成是手邊必備的利器。 


<

CharSequence

JDK 1.4定義了1個新的接口,叫CharSequence。它提供了StringStringBuffer這兩個類的字符序列的抽象:

interface CharSequence {
charAt(int i);
length();
subSequence(int start, int end);
toString();
}

為了實現這個新的CharSequence接口,StringStringBufferCharBuffer都作了修改。很多正則表達式的操作都要拿CharSequence作參數。

PatternMatcher

先給1個例子。下面這段程序可以測試正則表達式是不是匹配字符串。第1個參數是要匹配的字符串,后面是正則表達式。正則表達式可以有多個。在Unix/Linux環境下,命令行下的正則表達式還必須用引號。

//: c12:TestRegularExpression.java // Allows you to easly try out regular expressions. // {Args: abcabcabcdefabc "abc+" "(abc)+" "(abc){2,}" } import java.util.regex.*; publicclass TestRegularExpression { publicstaticvoid main(String[] args) { if(args.length < 2) { System.out.println("Usage:/n" + "java TestRegularExpression " + "characterSequence regularExpression+");
System.exit(0);
}
System.out.println("Input: /"" + args[0] + "/""); for(int i = 1; i < args.length; i++) { System.out.println( "Regular expression: /"" + args[i] + "/"");
Pattern p = Pattern.compile(args[i]);
Matcher m = p.matcher(args[0]); while(m.find()) {
System.out.println("Match /"" + m.group() + "/" at positions " +
m.start() + "-" + (m.end() - 1));
}
}
}
} ///:~

Java正則表達式是由java.util.regexPatternMatcher類實現的Pattern對象表示經編譯的正則表達式。靜態的compile( )方法負責將表示正則表達式的字符串編譯成Pattern對象。正如上述例程所示的,只要給Patternmatcher( )方法送1個字符串就可以獲得1個Matcher對象。另外,Pattern還有1個能快速判斷能否在input里面找到regex

staticboolean matches(?regex, ?input)

和能返回String數組的split( )方法,它能用regex把字符串分割開來。

只要給Pattern.matcher( )方法傳1個字符串就可以取得Matcher對象了。接下來就可以用Matcher的方法來查詢匹配的結果了。

boolean matches() boolean lookingAt() boolean find() boolean find(int start)

matches( )的條件是Pattern匹配全部字符串,而lookingAt( )的意思是Pattern匹配字符串的開頭。

find( )

Matcher.find( )的功能是發現CharSequence里的,與pattern相匹配的多個字符序列。例如:

//: c12:FindDemo.java import java.util.regex.*; import com.bruceeckel.simpletest.*; import java.util.*; publicclass FindDemo { privatestatic Test monitor = new Test(); publicstaticvoid main(String[] args) {
Matcher m = Pattern.compile("http://w+")
.matcher("Evening is full of the linnet's wings"); while(m.find())
System.out.println(m.group()); int i = 0; while(m.find(i)) {
System.out.print(m.group() + " ");
i++;
}
monitor.expect(new String[] { "Evening", "is", "full", "of", "the", "linnet", "s", "wings", "Evening vening ening ning ing ng g is is s full " + "full ull ll l of of f the the he e linnet linnet " + "innet nnet net et t s s wings wings ings ngs gs s " });
}
} ///:~

"//w+"的意思是"1個或多個單詞字符",因此它會將字符串直接分解成單詞。find( )像1個迭代器,從頭到尾掃描1遍字符串。第2個find( )是帶int參數的,正如你所看到的,它會告知方法從哪里開始找——即從參數位置開始查找。

Groups

Group是指里用括號括起來的,能被后面的表達式調用的正則表達式。Group 0 表示全部表達式,group 1表示第1個被括起來的group,以此類推。所以;

A(B(C))D

里面有3個group:group 0是ABCD, group 1是BC,group 2是C

你可以用下述Matcher方法來使用group:

public int groupCount( )返回matcher對象中的group的數目。不包括group0。

public String group( ) 返回上次匹配操作(比方說find( ))的group 0(全部匹配)

public String group(int i)返回上次匹配操作的某個group。如果匹配成功,但是沒能找到group,則返回null。

public int start(int group)返回上次匹配所找到的,group的開始位置。

public int end(int group)返回上次匹配所找到的,group的結束位置,最后1個字符的下標加1。

//: c12:Groups.java import java.util.regex.*; import com.bruceeckel.simpletest.*; publicclass Groups { privatestatic Test monitor = new Test(); staticpublicfinal String poem = "Twas brillig, and the slithy toves/n" + "Did gyre and gimble in the wabe./n" + "All mimsy were the borogoves,/n" + "And the mome raths outgrabe./n/n" + "Beware the Jabberwock, my son,/n" + "The jaws that bite, the claws that catch./n" + "Beware the Jubjub bird, and shun/n" + "The frumious Bandersnatch."; publicstaticvoid main(String[] args) {
Matcher m =
Pattern.compile("(?m)(//S+)//s+((//S+)//s+(//S+))___FCKpd___6quot;)
.matcher(poem); while(m.find()) { for(int j = 0; j <= m.groupCount(); j++) System.out.print("[" + m.group(j) + "]");
System.out.println();
}
monitor.expect(new String[]{ "[the slithy toves]" + "[the][slithy toves][slithy][toves]", "[in the wabe.][in][the wabe.][the][wabe.]", "[were the borogoves,]" + "[were][the borogoves,][the][borogoves,]", "[mome raths outgrabe.]" + "[mome][raths outgrabe.][raths][outgrabe.]", "[Jabberwock, my son,]" + "[Jabberwock,][my son,][my][son,]", "[claws that catch.]" + "[claws][that catch.][that][catch.]", "[bird, and shun][bird,][and shun][and][shun]", "[The frumious Bandersnatch.][The]" + "[frumious Bandersnatch.][frumious][Bandersnatch.]" });
}
} ///:~

這首詩是Through the Looking Glass的,Lewis Carroll的"Jabberwocky"的第1部份。可以看到這個正則表達式里有很多用括號括起來的group,它是由任意多個連續的非空字符('/S+')和任意多個連續的空格字符('/s+')所組成的,其終究目的是要捕獲每行的最后3個單詞;'$'表示1行的結尾。但是'$'通常表示全部字符串的結尾,所以這里要明確地告知正則表達式注意換行符。這1點是由'(?m)'標志完成的(模式標志會過1會講授)。

start( )和end( )

如果匹配成功,start( )會返回此次匹配的開始位置,end( )會返回此次匹配的結束位置,即最后1個字符的下標加1。如果之前的匹配不成功(或沒匹配),那末不管是調用start( )還是end( ),都會引發1個IllegalStateException。下面這段程序還演示了matches( )lookingAt( )

//: c12:StartEnd.java import java.util.regex.*; import com.bruceeckel.simpletest.*; publicclass StartEnd { privatestatic Test monitor = new Test(); publicstaticvoid main(String[] args) {
String[] input = new String[] { "Java has regular expressions in 1.4", "regular expressions now expressing in Java", "Java represses oracular expressions" };
Pattern
p1 = Pattern.compile("re//w*"),
p2 = Pattern.compile("Java.*"); for(int i = 0; i < input.length; i++) { System.out.println("input " + i + ": " + input[i]);
Matcher
m1 = p1.matcher(input[i]),
m2 = p2.matcher(input[i]); while(m1.find())
System.out.println("m1.find() '" + m1.group() + "' start = "+ m1.start() + " end = " + m1.end()); while(m2.find())
System.out.println("m2.find() '" + m2.group() + "' start = "+ m2.start() + " end = " + m2.end()); if(m1.lookingAt()) // No reset() necessary System.out.println("m1.lookingAt() start = " + m1.start() + " end = " + m1.end()); if(m2.lookingAt())
System.out.println("m2.lookingAt() start = " + m2.start() + " end = " + m2.end()); if(m1.matches()) // No reset() necessary System.out.println("m1.matches() start = " + m1.start() + " end = " + m1.end()); if(m2.matches())
System.out.println("m2.matches() start = " + m2.start() + " end = " + m2.end());
}
monitor.expect(new String[] { "input 0: Java has regular expressions in 1.4", "m1.find() 'regular' start = 9 end = 16", "m1.find() 'ressions' start = 20 end = 28", "m2.find() 'Java has regular expressions in 1.4'" + " start = 0 end = 35", "m2.lookingAt() start = 0 end = 35", "m2.matches() start = 0 end = 35", "input 1: regular expressions now " + "expressing in Java", "m1.find() 'regular' start = 0 end = 7", "m1.find() 'ressions' start = 11 end = 19", "m1.find() 'ressing' start = 27 end = 34", "m2.find() 'Java' start = 38 end = 42", "m1.lookingAt() start = 0 end = 7", "input 2: Java represses oracular expressions", "m1.find() 'represses' start = 5 end = 14", "m1.find() 'ressions' start = 27 end = 35", "m2.find() 'Java represses oracular expressions' " + "start = 0 end = 35", "m2.lookingAt() start = 0 end = 35", "m2.matches() start = 0 end = 35" });
}
} ///:~

注意,只要字符串里有這個模式,find( )就可以把它給找出來,但是lookingAt( )matches( ),只有在字符串與正則表達式1開始就相匹配的情況下才能返回truematches( )成功的條件是正則表達式與字符串完全匹配,而lookingAt( )成功的條件是,字符串的開始部份與正則表達式相匹配。

匹配的模式(Pattern flags)

compile( )方法還有1個版本,它需要1個控制正則表達式的匹配行動的參數:

Pattern Pattern.compile(String regex, int flag)
flag的取值范圍以下:
編譯標志 效果
Pattern.CANON_EQ 當且僅當兩個字符的"正規分解(canonical decomposition)"都完全相同的情況下,才認定匹配。比如用了這個標志以后,表達式"a/u030A"會匹配"?"。默許情況下,不斟酌"規范相等性(canonical equivalence)"。
Pattern.CASE_INSENSITIVE
(?i)
默許情況下,大小寫不明感的匹配只適用于US-ASCII字符集。這個標志能讓表達式疏忽大小寫進行匹配。要想對Unicode字符進行大小不明感的匹配,只要將UNICODE_CASE與這個標志合起來就好了。
Pattern.COMMENTS
(?x)
在這類模式下,匹配時會疏忽(正則表達式里的)空格字符(注:不是指表達式里的"http://s",而是指表達式里的空格,tab,回車之類)。注釋從#開始,1直到這行結束。可以通過嵌入式的標志來啟用Unix行模式。
Pattern.DOTALL
(?s)
在這類模式下,表達式'.'可以匹配任意字符,包括表示1行的結束符。默許情況下,表達式'.'不匹配行的結束符。
Pattern.MULTILINE
(?m)
在這類模式下,'^'和'$'分別匹配1行的開始和結束。另外,'^'依然匹配字符串的開始,'$'也匹配字符串的結束。默許情況下,這兩個表達式僅僅匹配字符串的開始和結束。
Pattern.UNICODE_CASE
(?u)
在這個模式下,如果你還啟用了CASE_INSENSITIVE標志,那末它會對Unicode字符進行大小寫不明感的匹配。默許情況下,大小寫不明感的匹配只適用于US-ASCII字符集。
Pattern.UNIX_LINES
(?d)
在這個模式下,只有'/n'才被認作1行的中斷,并且與'.','^',和'$'進行匹配。

在這些標志里面,Pattern.CASE_INSENSITIVEPattern.MULTILINE,和Pattern.COMMENTS是最有用的(其中Pattern.COMMENTS還能幫我們把思路理清楚,并且/或做文檔)。注意,你可以用在表達式里插記號的方式來啟用絕大多數的模式。這些記號就在上面那張表的各個標志的下面。你希望模式從哪里開始啟動,就在哪里插記號。

可以用"OR" ('|')運算符把這些標志合使用:

//: c12:ReFlags.java import java.util.regex.*; import com.bruceeckel.simpletest.*; publicclass ReFlags { privatestatic Test monitor = new Test(); publicstaticvoid main(String[] args) {
Pattern p = Pattern.compile("^java",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
Matcher m = p.matcher( "java has regex/nJava has regex/n" + "JAVA has pretty good regular expressions/n" + "Regular expressions are in Java"); while(m.find())
System.out.println(m.group());
monitor.expect(new String[] { "java", "Java", "JAVA" });
}
} ///:~

這樣創建出來的正則表達式就可以匹配以"java","Java","JAVA"...開頭的字符串了。另外,如果字符串分好幾行,那它還會對每行做匹配(匹配始于字符序列的開始,終究字符序列當中的行結束符)。注意,group( )方法僅返回匹配的部份。

split( )

所謂分割是指將以正則表達式為界,將字符串分割成String數組。

String[] split(CharSequence charseq)
String[] split(CharSequence charseq, int limit)

這是1種既快又方便地將文本根據1些常見的邊界標志分割開來的方法。

//: c12:SplitDemo.java import java.util.regex.*; import com.bruceeckel.simpletest.*; import java.util.*; publicclass SplitDemo { privatestatic Test monitor = new Test(); publicstaticvoid main(String[] args) {
String input = "This!!unusual use!!of exclamation!!points";
System.out.println(Arrays.asList(
Pattern.compile("!!").split(input))); // Only do the first three: System.out.println(Arrays.asList(
Pattern.compile("!!").split(input, 3)));
System.out.println(Arrays.asList( "Aha! String has a split() built in!".split(" ")));
monitor.expect(new String[] { "[This, unusual use, of exclamation, points]", "[This, unusual use, of exclamation!!points]", "[Aha!, String, has, a, split(), built, in!]" });
}
} ///:~

第2個split( )會限定分割的次數。

正則表達式是如此重要,以致于有些功能被加進了String類,其中包括split( )(已看到了),matches( )replaceFirst( )replaceAll( )。這些方法的功能同PatternMatcher的相同。

替換操作

正則表達式在替換文本方面特別在行。下面就是1些方法:

replaceFirst(String replacement)將字符串里,第1個與模式相匹配的子串替換成replacement

replaceAll(String replacement),將輸入字符串里所有與模式相匹配的子串全部替換成replacement

appendReplacement(StringBuffer sbuf, String replacement)sbuf進行逐次替換,而不是像replaceFirst( )replaceAll( )那樣,只替換第1個或全部子串。這是個非常重要的方法,由于它可以調用方法來生成replacement(replaceFirst( )replaceAll( )只允許用固定的字符串來充當replacement)。有了這個方法,你就能夠編程辨別group,從而實現更強大的替換功能。

調用完appendReplacement( )以后,為了把剩余的字符串拷貝回去,必須調用appendTail(StringBuffer sbuf, String replacement)

下面我們來演示1下怎樣使用這些替換方法。說明1下,這段程序所處理的字符串是它自己開頭部份的注釋,是用正則表達式提取出來并加以處理以后再傳給替換方法的。

//: c12:TheReplacements.java import java.util.regex.*; import java.io.*; import com.bruceeckel.util.*; import com.bruceeckel.simpletest.*; /*! Here's a block of text to use as input to
the regular expression matcher. Note that we'll
first extract the block of text by looking for
the special delimiters, then process the
extracted block. !*/ publicclass TheReplacements { privatestatic Test monitor = new Test(); publicstaticvoid main(String[] args) throws Exception {
String s = TextFile.read("TheReplacements.java"); // Match the specially-commented block of text above: Matcher mInput =
Pattern.compile("///*!(.*)!//*/", Pattern.DOTALL)
.matcher(s); if(mInput.find())
s = mInput.group(1); // Captured by parentheses // Replace two or more spaces with a single space: s = s.replaceAll(" {2,}", " "); // Replace one or more spaces at the beginning of each // line with no spaces. Must enable MULTILINE mode: s = s.replaceAll("(?m)^ +", "");
System.out.println(s);
s = s.replaceFirst("[aeiou]", "(VOWEL1)");
StringBuffer sbuf = new StringBuffer();
Pattern p = Pattern.compile("[aeiou]");
Matcher m = p.matcher(s); // Process the find information as you // perform the replacements: while(m.find())
m.appendReplacement(sbuf, m.group().toUpperCase()); // Put in the remainder of the text: m.appendTail(sbuf);
System.out.println(sbuf);
monitor.expect(new String[]{ "Here's a block of text to use as input to", "the regular expression matcher. Note that we'll", "first extract the block of text by looking for", "the special delimiters, then process the", "extracted block. ", "H(VOWEL1)rE's A blOck Of tExt tO UsE As InpUt tO", "thE rEgUlAr ExprEssIOn mAtchEr. NOtE thAt wE'll", "fIrst ExtrAct thE blOck Of tExt by lOOkIng fOr", "thE spEcIAl dElImItErs, thEn prOcEss thE", "ExtrActEd blOck. " });
}
} ///:~

TextFile.read( )方法來打開和讀取文件。mInput的功能是匹配'/*!' 和 '!*/' 之間的文本(注意1下分組用的括號)。接下來,我們將所有兩個以上的連續空格全都替換成1個,并且將各行開頭的空格全都去掉(為了讓這個正則表達式能對所有的行,而不單單是第1行起作用,必須啟用多行模式)。這兩個操作都用了StringreplaceAll( )(這里用它更方便)。注意,由于每一個替換只做1次,因此除預編譯

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 小草av在线 | 欧美日韩精品在线 | 天堂z丧尸电影免费观看 | 日本免费高清一区二区 | 国产一区二区在线免费观看 | 国产精品电影一区二区 | 日本特黄a级高清免费大片 韩国精品久久久 | 亚洲网在线 | а天堂中文官网 | 精品一区二区免费视频 | 成人国产精品156免费观看 | 九九热在线观看 | 亚洲a毛片| 精品国产乱码久久久久久蜜臀 | 国产毛片aaa | www视频在线观看 | 成人免费黄色 | 成人精品国产 | 日韩欧美一区二区在线视频 | 欧美日韩成人在线视频 | 18av在线播放 | 久久一区二区三区日韩 | 91久久久久久久久久久久久 | 91视频在线观看 | 综合精品久久 | 欧美日韩精品一区二区三区 | 国产福利av| 国产免费av网站 | 超碰娱乐 | 国产亚洲视频在线观看 | 91麻豆产精品久久久久久 | 久热九九 | 日韩在线视频一区 | 国产一区二区三区的电影 | 精品不卡在线 | 免费日韩一区二区三区 | 日本三级在线视频 | 日韩视频区 | 色一情一区二 | 国产一区二区三区视频在线 | 国产精品成人一区二区 |