正則表達式語法:html
語法 解釋 字符: c |字符c \unnnn, \xnn,\0n,\0nn,\0nnn |具備給定十六進制或十進制的碼元 \t,\n,\r,\f,\a,\e |控制符:製表符、換行符、回車符、換頁符、警告符、逃逸符 \cc |與字符c相關的控制符 字符類: [C1C2...] |任何由C1,C2...表示的字符,其中Ci能夠是多個字符、字符範圍是C1-C2或字符類 [^......] |字符類的補集 [...&&..] |兩個字符集的交集 預約義字符類: 除了行終止符以外全部的字符(在DOTALL標誌被設置時,則表示全部字符) \d |一個數字[0-9] \D |一個非數字[0-9] \s |一個空白字符[\t\n\t\f\x0B] \S |一個非空白字符 \w |一個詞語字符[a-zA-Z0-9] \W |一個非詞語字符 \p{name} |一個命名字符類 \P{name} |一個命名字符類的補集 邊界匹配符: ^$ |輸入的開頭和結尾 \b |一個詞語邊界 \B |一個非詞語字符 \A |輸入的開頭 \z |輸入的結尾 \Z |除了終止符以外的輸入結尾 \G |前一個匹配的結尾 量詞: X? |可選的X X* |X重複0或屢次 X+ |X重複1或屢次 X{n}X{n,}X{n,m} |X重複n次,至少n次,在n到m次之間 量詞後綴: ? |將默認(貪婪)匹配轉變爲勉強匹配 + |將默認(貪婪)匹配轉變爲佔有匹配 集合操做: XY |任何X中的字符串,後面跟隨任何Y中的字符串 X|Y |任何X或Y的字符串 羣組: (X) |捕獲將X做爲羣組匹配的字符串 \n |第n個羣組的匹配 轉義: \c |字符c(必須是不在字母表中的字符) \Q.....\E |逐字的引用... (?...) |特殊結構
咱們從簡單的開始,假設你要搜索一個包含字符cat的字符串,搜索用的正則表達式是cat。若是搜索對大小寫不敏感,單詞catalog、Catherine、sophisticated均可以匹配。也就是說:java
正則表達式:cat正則表達式
匹配:cat,catalog,Catherine,sophisticatedexpress
好比說,想要找出三個字母的單詞,並且這些單詞必須以t開頭,以n結束。另外,假設有一個字典,你能夠用正則表達式搜索所有內容。則能夠用t.n來進行匹配。編程
好比說,能夠用[]進行進一步匹配,避免過於普遍。小程序
正則表達式:t[aeio]n
數組
匹配:tan,Ten,tin,ton1.3 或符號服務器
若是除了上面匹配的全部單詞以外,你還想要匹配「toon」,那麼,你可使用「|」操做符。「|」操做符的基本意義就是「或」運算。要匹配 「toon」,使用「t(a|e|i|o|oo)n」正則表達式。這裏不能使用方擴號,由於方括號只容許匹配單個字符;這裏必須使用圓括號「()」。圓括 號還能夠用來分組。app
正則表達式:t(a|e|i|o|oo)nide
匹配:tan,ten,tin,ton,toon
見正則表達式語法的量詞。
如999-99-9999 [0-9]{3}\-[0-9]{2}\-[0-9]{4}
999999999和999-99-9999 [0-9]{3}\-?[0-9]{2}\-?[0-9]{4}
8836KV [0-9]{4}[a-z]{2}
^稱爲否符號,表示不想匹配的字符。如^a:第一個字符不能是a。[^a][a-z]+即:匹配開頭不是a的所有單詞。
如從June 26,1951的生日中提出月份部分,則能夠用:
[a-z]+ \s+[0-9]{1-2},\s*[0-9]{4}:匹配該日期的正則表達式。
([a-z]+) \s+[0-9]{1-2},\s*[0-9]{4}:匹配該日期的月份正則表達式。
設計一個簡單的表達式來匹配任何電話號碼數字多是比較複雜的事情,緣由在於電話號碼格式有不少種狀況。全部必須選擇一個比較有效的模式。好比:(212) 555-1212, 212-555-1212和212 555 1212,某些人會認爲它們都是等價的。
首先讓咱們構成一個正則表達式。爲簡單起見,先構成一個正則表達式來識別下面格式的電話號碼數字:(nnn)nnn-nnnn。
第一步,建立一個pattern對象來匹配上面的子字符串。一旦程序運行後,若是須要的話,可讓這個對象通常化。匹配上面格式的正則表達能夠這樣構成: (\d{3})\s\d{3}-\d{4},其中\d單字符類型用來匹配從0到9的任何數字,另外{3}重複符號,是個簡便的記號,用來表示有3個連續的 數字位,也等效於(\d\d\d)。\s也另一個比較有用的單字符類型,用來匹配空格,好比Space鍵,tab鍵和換行符。
是否是很簡單?可是,若是把這個正則表達式的模式用在java程序中,還要作兩件事。對java的解釋器來講,在反斜線字符(\)前的字符有特殊的 含義。在java中,與regex有關的包,並不都能理解和識別反斜線字符(/),儘管能夠試試看。但爲避免這一點,即爲了讓反斜線字符(\)在模式對象 中被徹底地傳遞,應該用雙反斜線字符(\\)。此外圓括號在正則表達中兩層含義,若是想讓它解釋爲字面上意思(即圓括號),也須要在它前面用雙反斜線字符 (\\)。也就是像下面的同樣:
\\(\\d{3}\\)\\s\\d{3}-\\d{4}
下面的一段代碼實現的功能是,從一個文本文件逐行讀入,並逐行搜索電話號碼數字,一旦找到所匹配的,而後輸出在控制檯。
1 package perl; 2 import java.io.*; 3 import java.util.regex.*; 4 public class test_number { 5 public static void main(String[] args) throws IOException{ 6 BufferedReader in; 7 Pattern pattern=Pattern.compile("\\(\\d{3}\\)\\s\\d{3}-\\d{4}"); 8 in=new BufferedReader(new FileReader("C:/Users/liuzhongfeng/Desktop/文件/java/phone.txt")); 9 String s; 10 while((s=in.readLine())!=null){ 11 Matcher matcher=pattern.matcher(s); 12 if(matcher.find()){ 13 System.out.println(matcher.group()); 14 } 15 } 16 in.close(); 17 } 18 }
結果爲:
(121) 525-1111 (000) 545-5555 (000) 545-5555 原文爲: (121) 525-1111 (000) 545-5555 (000)-545-5555 (000) 545-55555 (000)-545-5555
對於程序中的find()函數,用來匹配搜索與正則表達式相匹配id任何目標字符串,group()方法,用來返回包含了所匹配文本的字符串,應注意的是,上面的代碼,僅用在每行只能含有一個匹配的電話號碼數字字符串時。能夠確定的說,java的正則表達式包能用在一行含有多個匹配目標時的搜索。這至關漂亮吧! 可是很遺憾的是,這僅是個電話號碼匹配器。
很明顯,還有兩點能夠改進。若是在電話號碼的開頭,即區位號和本地號碼之間可能會有空格。咱們也可匹配這些狀況,則經過在正則表達式中加入/s?來實現,其中?元字符表示在模式可能有0或1個空格符。
第二點是,在本地號碼位的前三位和後四位數字間有多是空格符,而不是連字號,更有勝者,或根本就沒有分隔符,就是7位數字連在一塊兒。對這幾種狀況,咱們 能夠用(-|)?來解決。這個結構的正則表達式就是轉換器,它能匹配上面所說的幾種狀況。在()能含有管道符|時,它能匹配是否含有空格符或連字符,而尾 部的?元字符表示是否根本沒有分隔符的狀況。最後,區位號也可能沒有包含在圓括號內,對此能夠簡單地在圓括號後附上?元字符,但這不是一個很好的解決方法。由於它也包含了不配對的圓括號,好比" (555" 或 "555)"。相反,咱們能夠經過另外一種轉換器來強迫讓電話號碼是否帶有有圓括號:(\(\d{3}\)|\d{3})。若是咱們把上面代碼中的正則表達 式用這些改進後的來替換的話,上面的代碼就成了一個很是有用的電話號碼數字匹配器:Pattern pattern =Pattern.compile("(\\(\\d{3}\\)|\\d{3})\\s?\\d{3}(-|)?\\d{4}");
能夠肯定的是,你能夠本身試着進一步改進上面的代碼。
1.第二個例子:它是從Friedl的中改編過來的,其功能是檢查文本中是否有重複的單詞,這在印刷排版中會常常遇到,一樣也是個語法檢查器的問題。
匹配單詞好幾種正則表達式,最可能直接的是\b\w+\b,優勢是隻需少許的regex元字符。其中/w元字符用來匹配從字母a到u的任何字符。+元字符表示匹配匹配一次或屢次字符,/b元字符是用來講明匹配單詞的邊界,它能夠是空格或任何一種不一樣的標點符號(包括逗號,句號等)。
圓括號在正則表達式中有幾種不一樣的用法,一個就是能提供組合類型,組合類型用來保存所匹配的結果或部分匹配的結果(以便後面能用到),即便遇到有相同的模 式。在一樣的正則表達中,可能(也一般指望)不止有一個組合類型。在第n個組合類型中匹配結果能夠經過向後掃描來獲取到。向後掃描使得搜索重複的單詞很是 簡單:\b(\w+)\s+\1\b。向後掃描\1,指的是任何被\w+所匹配的單詞。咱們的正則表達式所以能匹配這樣的,它有一個或多個空格符,後面還跟有一個與此相同的單詞。
最後進一步的修改是讓咱們的匹配器對大小寫敏感。好比,下面的狀況:"The the theme of this article is the Java's regex package.",這一點在regex中能很是簡單地實現,即經過使用在Pattern類中預約義的靜態標誌CASE_INSENSITIVE。
pattern pattern=Pattern.compile("\\b(\\w+)\\s+\\1\\b");
Pattern.CASE_INSENSITIVE();
JDK 1.4定義了一個新的接口,它提供了String和StringBuffer這兩個類的字符序列的抽象。
interface CharSequence{
charAt(int i);
length();
subSequence(int start,int end);
toString();
}
先給一個例子。下面這段程序能夠測試正則表達式是否匹配字符串。第一個參數是要匹配的字符串,後面是正則表達式。正則表達式能夠有多個。在Unix/Linux環境下,命令行下的正則表達式還必須用引號。
Java的正則表達式是由java.util.regex的Pattern和Matcher類實現的。Pattern對象表示經編譯的正則表達式。靜態的compile( )方法負責將表示正則表達式的字符串編譯成Pattern對象。正如上述例程所示的,只要給Pattern的matcher( )方法送一個字符串就能獲取一個Matcher對象。只要給Pattern matcher()方法傳一個字符串就可以得到Matcher的方法來查詢匹配的結果了。
boolean matches()
boolean lookingAt()
boolean find()
boolean find(int start)
matches()的前提是Pattern匹配整個字符串,而lookingAt()的意思是Pattern匹配字符串的開頭。對於find()函數,Matcher.find()的功能是發現CharSequence裏的,與pattern相匹配的多個字符序列。例如:
1 package perl; 2 3 import java.util.regex.*; 4 //import com.bruceeckel.simpletest.* 5 import javax.management.monitor.*; 6 import java.util.*; 7 import java.io.*; 8 public class FindDemo { 9 public static void main(String[] args) throws IOException{ 10 BufferedReader in;String str; 11 in=new BufferedReader(new FileReader("C:/Users/liuzhongfeng/Desktop/文件/java/find.txt")); 12 Matcher m=Pattern.compile("\\w+").matcher("Evening is full of the linnet's wings"); 13 while((str=in.readLine())!=null){ 14 while(m.find()){ 15 System.out.println(m.group()); 16 } 17 int i=0; 18 while(m.find(i)){ 19 System.out.print(m.group()+" "); 20 i++; 21 } 22 } 23 in.close(); 24 } 25 }
輸出結果爲:
Evening is full of the linnet s 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 原文是: "Evening","is","full","of","the","linnet","s","wings",
"Eveing vening ening ning ing ng g is is a full full ull ll l of of f the the the he e linnet linnet innet nnet net et t s s wings wings ings ngs gs s a"
"\\w+"的意思是「一個或多個單詞字符」,所以它將會將字符串直接分解成單詞。find()像一個迭代器,從頭至尾掃描一遍字符串。而第二個find()是帶int參數的,它將會告訴你,從那個位置開始查找--從參數的位置開始查找。
Group是指裏用括號括起來的,能被後面的表達式調用的正則表達式。Group 0表示整個表達式,group 1表示第一個被括起來的group,以次類推。好比:
A(B(C))D 有三個group:group 0是ABCD,gourp 1是BC,group 2是C。
這是一些經常使用的grou方法:
public int groupCount()返回matcher對象中的group的數目。不包括group 0
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 package perl; 2 import java.util.regex.*; 3 import java.io.*; 4 public class test1 { 5 static public final String poem="Twas brillig, and the slithy toves/n" + 6 "Did gyre and gimble in the wabe./n" + 7 "All mimsy were the borogoves,/n" + 8 "And the mome raths outgrabe./n/n" + 9 "Beware the Jabberwock, my son,/n" + 10 "The jaws that bite, the claws that catch./n" + 11 "Beware the Jubjub bird, and shun/n" + 12 "The frumious Bandersnatch."; 13 public static void main(String[] args) throws IOException{ 14 //BufferedReader in; 15 //in=new BufferedReader(new FileReader("C:/Users/liuzhongfeng/Desktop/文件/java/find1.txt")); 16 Matcher m=Pattern.compile("(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))").matcher(poem); 17 //while(in.readLine()!=null){ 18 while(m.find()){//查找是否有單個單詞匹配,有則輸出 19 for(int j=0;j<=m.groupCount();j++){ 20 System.out.println("["+m.group(j)+"]"); 21 } 22 System.out.println(); 23 } 24 //} 25 //in.close(); 26 } 27 }
結果是:
[Twas brillig, and] [Twas] [brillig, and] [brillig,] [and] [the slithy toves/nDid] [the] [slithy toves/nDid] [slithy] [toves/nDid] [gyre and gimble] [gyre] [and gimble] [and] [gimble] [in the wabe./nAll] [in] [the wabe./nAll] [the] [wabe./nAll] [mimsy were the] [mimsy] [were the] [were] [the] [borogoves,/nAnd the mome] [borogoves,/nAnd] [the mome] [the] [mome] [raths outgrabe./n/nBeware the] [raths] [outgrabe./n/nBeware the] [outgrabe./n/nBeware] [the] [Jabberwock, my son,/nThe] [Jabberwock,] [my son,/nThe] [my] [son,/nThe] [jaws that bite,] [jaws] [that bite,] [that] [bite,] [the claws that] [the] [claws that] [claws] [that] [catch./nBeware the Jubjub] [catch./nBeware] [the Jubjub] [the] [Jubjub] [bird, and shun/nThe] [bird,] [and shun/nThe] [and] [shun/nThe]
這首詩是Through the Looking Glass的,Lewis Carroll的"Jabberwocky"的第一部分。能夠看到這個正則表達式裏有不少用括號括起來的group,它是由任意多個連續的非空字符('/S+')和任意多個連續的空格字符('/s+')所組成的,其最終目的是要捕獲每行的最後三個單詞;'$'表示一行的結尾。可是'$'一般表示整個字符串的結尾,因此這裏要明確地告訴正則表達式注意換行符。這一點是由'(?m)'標誌完成的(模式標誌會過一會講解)。
若是匹配成功,start返回匹配開始的位置,end()返回匹配結束的位置,即最後一個字符的下標加一。若是以前的匹配不成功(或者沒匹配),那麼不管是調用start( )仍是end( ),都會引起一個IllegalStateException。下面這段程序還演示了matches( )和lookingAt( ):
1 package perl; 2 import java.io.*; 3 import java.util.regex.*; 4 public class test2 { 5 public static void main(String[] args) throws IOException{ 6 String[] input=new String[]{"Java has regular expressions in 1.4", 7 "regular expressions now expressing in Java", 8 "Java represses oracular expressions"}; 9 Pattern p1=Pattern.compile("re\\w*"),p2=Pattern.compile("Java.*"); 10 for(int i=0;i<input.length;i++){ 11 System.out.println("input "+i+": "+input[i]); 12 Matcher m1=p1.matcher(input[i]),m2=p2.matcher(input[i]); 13 while(m1.find()){ 14 System.out.println("m1.find() '"+m1.group()+"start="+m1.start()+"end="+m1.end()); 15 } 16 while(m2.find()){ 17 System.out.println("m2.find() '"+m2.group()+"start="+m2.start()+"end="+m2.end()); 18 } 19 if(m1.lookingAt()){//No reset() necessary 20 System.out.println("m1.lookingAt() start= "+m1.start()+"end= "+m1.end()); 21 } 22 if(m2.lookingAt()){ 23 System.out.println("m2.lookingAt() start= "+m2.start()+"end= "+m2.end()); 24 } 25 if(m1.matches()){//No reset() necessary 26 System.out.println("m1.matches() start= "+m1.start()+"end= "+m1.end()); 27 } 28 if(m2.matches()){ 29 System.out.println("m2.matches() start= "+m2.start()+"end= "+m2.end()); 30 } 31 } 32 } 33 34 35 }
結果爲:
input 0: Java has regular expressions in 1.4 m1.find() 'regularstart=9end=16 m1.find() 'ressionsstart=20end=28 m2.find() 'Java has regular expressions in 1.4start=0end=35 m2.lookingAt() start= 0end= 35 m2.matches() start= 0end= 35 input 1: regular expressions now expressing in Java m1.find() 'regularstart=0end=7 m1.find() 'ressionsstart=11end=19 m1.find() 'ressingstart=27end=34 m2.find() 'Javastart=38end=42 m1.lookingAt() start= 0end= 7 input 2: Java represses oracular expressions m1.find() 'repressesstart=5end=14 m1.find() 'ressionsstart=27end=35 m2.find() 'Java represses oracular expressionsstart=0end=35 m2.lookingAt() start= 0end= 35 m2.matches() start= 0end= 35
注意,只要字符串有這個模式,find()就能把它找出來,可是lookingAt()和matches(),只有在字符串與正則表達式一開始就匹配的狀況下才能返回true,matches()成功的前提是正則表達式必須與字符串徹底匹配,而lookingAt()前提是,字符串的開始部分與正則表達式相匹配。匹配的模式(Pattern flags)
compile()方法還有一個版本,它須要一個控制正則表達式的匹配行爲的參數:
Pattern Pattern.compile(String regex,int flag)
編譯標誌: 效果: Pattern.CANON_EQ 當且僅當兩個字符的"正規分解(canonical decomposition)" 都徹底相同的狀況下,才認定匹配。好比用了這個標誌以後,表達式"a/u030A"會匹配"?"。 默認狀況下,不考慮"規範相等性(canonical equivalence)"。 Pattern.CASE_INSENSITIVE(?i) 默認狀況下,大小寫不明感的匹配只適用於US-ASCII字符集。 這個標誌能讓表達式忽略大小寫進行匹配。要想對Unicode字符進行大小不明感的匹配, 只要將UNICODE_CASE與這個標誌合起來就好了。 Pattern.COMMENTS(?x) 在這種模式下,匹配時會忽略(正則表達式裏的)空格字符(注:不是指表達式裏的"//s", 而是指表達式裏的空格,tab,回車之類)。註釋從#開始,一直到這行結束。 能夠經過嵌入式的標誌來啓用Unix行模式。 Pattern.DOTALL(?s) 在這種模式下,表達式'.'能夠匹配任意字符,包括表示一行的結束符。默認狀況下,表達式'.'不匹配行的結束符。 Pattern.MULTILINE(?m) 在這種模式下,'^'和'$'分別匹配一行的開始和結束。此外,'^'仍然匹配字符串的開始,'$'也匹配字符串的結束。 默認狀況下,這兩個表達式僅僅匹配字符串的開始和結束。 Pattern.UNICODE_CASE(?u) 在這個模式下,若是你還啓用了CASE_INSENSITIVE標誌,那麼它會對Unicode字符進行大小寫不明感的匹配。 默認狀況下,大小寫不明感的匹配只適用於US-ASCII字符集。 Pattern.UNIX_LINES(?d) 在這個模式下,只有'/n'才被認做一行的停止,而且與'.','^',以及'$'進行匹配
在這些標誌裏面,Pattern.CASE_INSENSITIVE,Pattern.MULTILINE,以及Pattern.COMMENTS是最有用的(其中Pattern.COMMENTS還能幫咱們把思路理清楚,而且/或者作文檔)。注意,你能夠用在表達式裏插記號的方式來啓用絕大多數的模式。這些記號就在上面那張表的各個標誌的下面。你但願模式從哪裏開始啓動,就在哪裏插記號。
能夠用"OR" ('|')運算符把這些標誌合使用:
1 package perl; 2 3 import java.util.regex.*; 4 5 public class Test3 { 6 public static void main(String[] args){ 7 String[] in=new String[]{"java has regular expressions in 1.4", 8 "regular expressions now expressing in Java", 9 "Java represses oracular expressions"}; 10 Pattern p=Pattern.compile("^java",Pattern.CASE_INSENSITIVE|Pattern.MULTILINE); 11 for(int i=0;i<in.length;i++){ 12 Matcher m=p.matcher(in[i]); 13 while(m.find()){ 14 System.out.println(m.group()); 15 } 16 } 17 } 18 }//CASE_INSENSITIVE不區分大小寫,因此只要是小寫是java都能搜到。並且MULTILINE模式^表明了每一個字符串的開始位置。
結果爲:
java
Java
所謂分割是指將以正則表達式爲界,將字符串分割成String數組。方法:
String[] split(CharSequence charseq)
String[] split(CharSequence charseq,int limit)
這是一種既快又方便地將文本根據一些常見的邊界標誌分割開來的方法。
替換操做
正則表達式在替換文本方面特別在行。下面就是一些方法:
replaceFirst(String replacement)將字符串裏,第一個與模式相匹配的子串替換成replacement。
replaceAll(String replacement),將輸入字符串裏全部與模式相匹配的子串所有替換成replacement
appendReplacement(StringBuffer sbuf, String replacement)對sbuf進行逐次替換,而不是像replaceFirst( )或replaceAll( )那樣,只替換第一個或所有子串。這是個很是重要的方法,由於它能夠調用方法來生成replacement(replaceFirst( )和replaceAll( )只容許用固定的字符串來充當replacement)。有了這個方法,你就能夠編程區分group,從而實現更強大的替換功能。
調用完appendReplacement( )以後,爲了把剩餘的字符串拷貝回去,必須調用appendTail(StringBuffer sbuf, String replacement)。
1 package perl; 2 3 import java.util.regex.*; 4 5 public class test5 { 6 public static void main(String[] args){ 7 String s="/*! Here's a block of text to use as input to"+ 8 "the regular expression matcher. Note that we'll"+ 9 "first extract the block of text by looking for"+ 10 "the special delimiters, then process the"+ 11 "extracted block. !*/"; 12 Matcher mInput=Pattern.compile("\\/*!(.*)!\\*/",Pattern.DOTALL).matcher(s); 13 if(mInput.find()) 14 s=mInput.group(1); 15 s=s.replaceAll(" {2,}"," "); 16 s=s.replaceAll("(?m)^ +",""); 17 System.out.println(s); 18 s=s.replaceFirst("[aeiou]", "(VOWEL1)");//只是替換aeiou第一個出現的, 19 StringBuffer sbuf=new StringBuffer(); 20 Pattern p=Pattern.compile("[aeiou]"); 21 Matcher m=p.matcher(s); 22 while(m.find()){ 23 m.appendReplacement(sbuf, m.group().toUpperCase()); 24 }//把小寫的aeiou所有替換成大寫 25 m.appendTail(sbuf); 26 System.out.println(sbuf); 27 } 28 }
結果爲:
Here's a block of text to use as input tothe regular expression matcher. Note that we'llfirst extract the block of text by looking forthe special delimiters, then process theextracted block.
H(VOWEL1)rE's A blOck Of tExt tO UsE As InpUt tOthE rEgUlAr ExprEssIOn mAtchEr. NOtE thAt wE'llfIrst ExtrAct thE blOck Of tExt by lOOkIng fOrthE spEcIAl dElImItErs, thEn prOcEss thEExtrActEd blOck.
replaceFirst( )只替換第一個子串。此外,replaceFirst( )和replaceAll( )只能用常量(literal)來替換,因此若是每次替換的時候還要進行一些操做的話,它們是無能爲力的。碰到這種狀況,得用appendReplacement( ),它能在進行替換的時候想寫多少代碼就寫多少。在上面那段程序裏,建立sbuf的過程就是選group作處理,也就是用正則表達式把元音字母找出來,而後換成大寫的過程。一般你得在完成所有的替換以後才調用appendTail( ),可是若是要模仿replaceFirst( )(或"replace n")的效果,你也能夠只替換一次就調用appendTail( )。它會把剩下的東西全都放進sbuf。
此外,還能夠用reset( )方法給現有的Matcher對象配上個新的CharSequence。
1 package perl; 2 3 import java.util.regex.*; 4 5 public class test6 { 6 public static void main(String[] args){ 7 Matcher m=Pattern.compile("[frb][aiu][gx]").matcher("fix the rug with bags"); 8 System.out.print("原來的 結果:"); 9 while(m.find()) 10 System.out.print(m.group()+" "); 11 System.out.println(); 12 System.out.print("後來的reset結果:"); 13 m.reset("fix the rig with rags"); 14 while(m.find()) 15 System.out.print(m.group()+" "); 16 } 17 }
結果爲:
原來的 結果:fix rug bag
後來的reset結果:fix rig rag
任務:分析一個Web服務器的日誌文件,肯定每個用戶花在網站上的時間。格式以下:
172.26.155.241 - - [26/Feb/2001:10:56:03 -0500]
"GET /sAlive.htm HTTP/1.0" 200 15
要從這個日誌文件提取的內容有兩項:IP地址和頁面訪問時間。能夠用分組符號(圓括號)從日誌記錄提取出IP地址和時間標記。
(\d{1,3}\.\d{1.3}\.d{1,3}\.\d{1,3})\s-\s\-\s \[([^]]+)\]
下面一個任務是分析HTML頁面內FONT標記的全部屬性。HTML頁面內典型的FONT標記以下所示:
程序將按照以下形式,輸出每個FONT標記的屬性:
採起步驟:先提取出「"face="Arial, Serif" size="+2" color="red"」。
< \s* font \s* ([^>]*) \s* >
而後提取第二個正則表達式:
([a-z]+) \s* = \s* " ([^"]+) "
分割的結果爲:
咱們假定Web服務器從widgets.acme.com移到了newserver.acme.com。如今你要修改一些頁面中的連接:
首先匹配修改前的連接:
<\s* a \s+href\s*=\s* "http://widgets.acme.com/interface.html ( [^"]+)">
若是可以匹配這個正則表達式,你能夠用下面的內容替換上邊的連接:
該程序是用來檢驗一個輸入的EMAIL地址裏所包含的字符是否合法,雖然這不是一個完整的EMAIL地址檢驗程序,它不能檢驗全部可能出現的狀況,但在必要時您能夠在其基礎上增長所需功能。
1 package perl; 2 3 import java.util.*; 4 import java.util.regex.*; 5 6 public class test7 { 7 public static void main(String[] args){ 8 System.out.println("請輸入EMALL地址:"); 9 Scanner in = new Scanner(System.in); 10 String input = in.next(); 11 //檢測輸入的EMAIL地址是否以 非法符號"."或"@"做爲起始字符 12 Pattern p=Pattern.compile("^\\.|^\\@"); 13 Matcher m=p.matcher(input); 14 if(m.find()){ 15 System.out.println("EMAIL地址不能以'.'或'@'做爲起始字符"); 16 } 17 Pattern p1=Pattern.compile("^www\\."); 18 Matcher m1=p1.matcher(input); 19 if(m1.find()){ 20 System.out.println("EMAIL地址不能以'www.'起始"); 21 } 22 23 Pattern p2=Pattern.compile("[A-Za-z0-9\\.\\@_\\-~#]+"); 24 Matcher m2=p2.matcher(input); 25 StringBuffer sb=new StringBuffer(); 26 boolean result=m2.find(); 27 boolean deletedIllegalChars=false; 28 while(result){//若是找到了非法字符那麼就設下標記 29 deletedIllegalChars=true; 30 //若是裏面包含非法字符如冒號雙引號等,那麼就把他們消去,加到SB裏面 31 m2.appendReplacement(sb, ""); 32 result=m2.find(); 33 } 34 m2.appendTail(sb); 35 if(deletedIllegalChars){ 36 System.out.println("輸入的EMALL地址包含有冒號,都好等非法字符,請從新輸入"); 37 } 38 } 39 40 }
轉載:http://blog.csdn.net/allwefantasy/article/details/3136570