標籤:
轉自:http://www.itzhai.com/java-notes-regex-matches-and-lookingat.html#read-more
1、基本文法2、String內建的Regex功能 2.1、String類內建的Regex工具 2.1.1、split方法 2.1.2、字串替換之replaceFirst和replaceAll方法3、建立Regex: 3.1、Pattern和Matcher 3.1.2、matches()與lookingAt()的使用 3.2、Group 3.3、Pattern標記 3.4、split()方法 3.5、替換操作 3.6、reset()方法4、Regex與Java I/O
本文主要內容:
- Regex最基本的文法;
- String內建的Regex功能,常用方法:split(), replaceFirst(), replaceAll();
- 使用Java建立Regex,相關類:Pattern, Matcher, Group;
- Pattern標記的介紹,使用Pattern.complie(String regex, int flag)給Regex指定模式;
- Pattern中的split方法,與String中的split類似;
- Matcher的替換操作,常用方法:replaceAll(String replacement), replaceFirst(String replacement), appendReplacement(StringBuffer sb, String replacement) , appendTail(StringBuffer sb);
- Matcher中reset()方法的使用;
- 在JAVA I/O中使用Regex。
很久以前,Regex就整合到了Unix工具集中,例如sed和awk,也整合到了Python和Perl之類的程式設計語言中。Java中的字串操作還主要集中在String,StringBuffer和StringTokenizer類,提供的功能相比於Regex簡單有限。
1、基本文法:
關於Java中的Regex詳細的文法,可以參考JDK文檔。
\\ 在其他語言中\\表示在Regex中插入一個普通的反斜線,而Java中則表示插入Regex的反斜線,所以其後的字元具有特殊的意義。
\\d 表示一位元字
\\\\ 表示普通的反斜線
\n\t 表示換行和定位字元,只需要使用單反斜線
-?\\d+ 表示可能有一個負號,後面跟著一位或多位元字 2、String內建的Regex功能:
String str ="-123";boolean isNum = str.matches("(-|\\+)?\\d+");// 可能包含負號或者正號的整數System.out.println(isNum);// output: true
2.1、String類內建的Regex工具: 2.1.1、split方法:
這是String中提供的一個非常有用的Regex工具,作用是將字串從Regex匹配的地方分開。
// split方法示範String content ="Hello, this is an iPad.";String[] items = content.split("\\W+");// 使用非單詞字元分割字串System.out.println(Arrays.toString(items));// [Hello, this, is, an, iPad] 可以發現逗號也被當做分隔字元給去掉了
// split方法的重載版本,允許你限制字串分割的次數items = content.split("\\W+",3);System.out.println(Arrays.toString(items));// [Hello, this, is an iPad.]
2.1.2、字串替換之replaceFirst和replaceAll方法:
// 字串的替換 replaceFirst和replaceAll方法String str ="You make me cry, make me smile.";System.out.println(str.replaceFirst("m\\w+","music"));// You music me cry, make me smile.System.out.println(str.replaceAll("make|me","music"));// You music music cry, music music smile.
3、建立Regex: 3.1、Pattern和Matcher:
為了更加方便的使用Regex,強烈建議多去瀏覽JDK文檔中java.util.regex.Pattern那一頁的內容。
下面是一個用Java建立Regex的例子:
String content ="one step tototoo far.";// 編譯Regex產生一個Pattern對象Pattern p =Pattern.compile("(to){2,}");// 用Pattern對象的matcher()方法檢索字串,產生Matcher對象Matcher m = p.matcher(content);while(m.find()){ System.out.println("Match \""+ m.group()+"\" ad position "+ m.start()+"-"+(m.end()-1));// output: Match "tototo" ad position 9-14}
使用Matcher上的各種方法,可以判斷各種不同類型的匹配是否成功:
boolean matches():
嘗試將整個地區與模式比對。
如果匹配成功,則可以通過 start、end 和 group 方法擷取更多資訊。
返回:
若且唯若整個地區序列匹配此匹配器的模式時才返回 true。
boolean lookingAt():
嘗試將從地區開頭開始的輸入序列與該模式比對。
與 matches 方法類似,此方法始終從地區的開頭開始;與之不同的是,它不需要匹配整個地區。
如果匹配成功,則可以通過 start、end 和 group 方法擷取更多資訊。
返回:
若且唯若輸入序列的首碼匹配此匹配器的模式時才返回 true。
boolean find():
嘗試尋找與該模式比對的輸入序列的下一個子序列。
此方法從匹配器地區的開頭開始,如果該方法的前一次調用成功了並且從那時開始匹配器沒有被重設,則從以前匹配操作沒有匹配的第一個字元開始。
如果匹配成功,則可以通過 start、end 和 group 方法擷取更多資訊。
返回:
若且唯若輸入序列的子序列匹配此匹配器的模式時才返回 true。
boolean find(int start):
重設此匹配器,然後嘗試尋找匹配該模式、從指定索引開始的輸入序列的下一個子序列。
如果匹配成功,則可通過 start、end 和 group 方法擷取更多資訊,而 find() 方法的後續調用將從此匹配操作未匹配的第一個字元開始。
返回:
若且唯若從給定索引開始的輸入序列的子序列匹配此匹配器的模式時才返回 true。
拋出:
IndexOutOfBoundsException- 如果開始點小於零或大於輸入序列的長度。
下面是一個使用 boolean find(int start)的例子:
// boolean find(int start)String content ="wings you are the hero~";Pattern p =Pattern.compile("\\w+");Matcher m = p.matcher(content);int i=0;while(m.find(i)){ System.out.print(m.group()+" "); i++;}
輸出內容為:
wings ings ngs gs s you you ou u are are re e the the he e hero hero ero ro o
. . . 請查看原文章 . . 3.5、替換操作:
主要看到Matcher的以下幾個方法:
replaceAll
public String replaceAll(String replacement)
-
替換模式與給定替換字串相匹配的輸入序列的每個子序列。
replaceFirst
public String replaceFirst(String replacement)
-
替換模式與給定替換字串匹配的輸入序列的第一個子序列。
appendReplacement
public Matcher appendReplacement(StringBuffer sb, String replacement)
-
實現非終端添加和替換步驟。此方法執行以下操作:
- 它從添加位置開始在輸入序列讀取字元,並將其添加到給定字串緩衝區。在讀取以前匹配之前的最後字元(即位於索引
start() - 1 處的字元)之後,它就會停止。
- 它將給定替換字串添加到字串緩衝區。
- 它將此匹配器的添加位置設定為最後匹配位置的索引加 1,即
end()。
appendTail
public StringBuffer appendTail(StringBuffer sb)
-
實現終端添加和替換步驟。此方法從添加位置開始從輸入序列讀取字元,並將其添加到給定字串緩衝區。可以在一次或多次調用
appendReplacement 方法後調用它來複製剩餘的輸入序列。
下面通過一個程式來示範一下這幾個方法的使用,並且通過這個程式,更加熟悉Regex的使用:
String content = "/*! long long ago, the is a man called Jack, \n" + " he has one boat. !*/";// Pattern.DOTALL: 這種模式下 . 可以匹配任何字元,包括分行符號Pattern p = Pattern.compile("/\\*!(.*)!\\*/", Pattern.DOTALL);Matcher m = p.matcher(content);if(m.find()) // 匹配到/*! !*/中的內容content = m.group(1);// 把兩個以上空格的地方縮減為一個空格content = content.replaceAll(" {2,}", " ");// 開啟多行模式,刪除每一行開頭部分的空格,+表示匹配一個或多個content = content.replaceAll("(?m)^ +", "");// 匹配到字串中的第一個母音字母,並替換為VOWELcontent = content.replaceFirst("[aeiou]", "VOWEL");// 下面一段程式示範把字串中的所有母音字母替換為大寫Pattern p1 = Pattern.compile("[aeiou]");Matcher m1 = p1.matcher(content);StringBuffer sb = new StringBuffer();while(m1.find()){ // 非終端添加和替換, m1.appendReplacement(sb, m1.group().toUpperCase());}// 終端添加和替換m1.appendTail(sb);System.out.println(sb);
輸出結果為:
lVOWELng lOng AgO, thE Is A mAn cAllEd JAck, hE hAs OnE bOAt.
注意,上面的兩個替換操作都只使用了一次replaceAll(),所以,與其編譯為Pattern,不如直接使用String的replaceAll()方法,而且開銷也比較小。
.
.
.
.
Java Pattern Matcher 正則應用