javaRegex通過java.util.regex包下的Pattern類與Matcher類實現(建議在閱讀本文時,開啟java API文檔,當介紹到哪個方法時,查看java API中的方法說明,效果會更佳).
Pattern類用於建立一個Regex,也可以說建立一個匹配模式,它的構造方法是私人的,不可以直接建立,但可以通過Pattern.complie(String regex)簡單Factory 方法建立一個Regex。
範例程式碼
package com.yulore.regex;import java.util.regex.Matcher;import java.util.regex.Pattern;public class RegexPatternTest {/** * @param args */public static void main(String[] args) {// search();// split();//replace();//matches();groupTest02();}/** * 當使用matches(),lookingAt(),find()執行匹配操作後,就可以利用以上三個方法得到更詳細的資訊. start()返回匹配到的子字串在字串中的索引位置. end()返回匹配到的子字串的最後一個字元在字串中的索引位置. group()返回匹配到的子字串 */public static void groupTest(){Pattern p = Pattern.compile("\\d+"); Matcher m = p.matcher("aaa2223bb"); m.find();//匹配2223 //m.start();//返回3 m.end();//返回7,返回的是2223後的索引號 m.group();//返回2223 System.out.println("start="+m.start()+">>end="+m.end()+">>group="+m.group());m = p.matcher("2223bb"); m.lookingAt(); //匹配2223 // m.start(); //返回0,由於lookingAt()只能匹配前面的字串,所以當使用lookingAt()匹配時,start()方法總是返回0 //m.end(); //返回4 m.group(); //返回2223 System.out.println("start="+m.start()+">>end="+m.end()+">>group="+m.group());m = p.matcher("2223bb"); m.matches(); //匹配整個字串 //m.start(); //返回0,原因相信大家也清楚了 //m.end(); //返回6,原因相信大家也清楚了,因為matches()需要匹配所有字串 m.group(); //返回2223bb System.out.println("start="+m.start()+">>end="+m.end()+">>group="+m.group());}/** * start(),end(),group()均有一個重載方法它們是start(int i),end(int i),group(int i) * 專用於分組操作,Mathcer類還有一個groupCount()用於返回有多少組. */private static void groupTest02(){Pattern p=Pattern.compile("([a-z]+)(\\d+)"); Matcher m=p.matcher("aaa2223bb"); boolean flag = m.find(); //匹配aaa2223 int count = m.groupCount(); //返回2,因為有2組 System.out.println("flag="+flag+">>groupCount="+count);int start = m.start(1); //返回0 返回第一組匹配到的子字串在字串中的索引號 int end = m.end(1); //返回3 返回第一組匹配到的子字串的最後一個字元在字串中的索引位置. System.out.println("start 1 ="+start+">>"+"end 1 ="+end);start = m.start(2); //返回3 end = m.end(2); //返回7 System.out.println("start 2 ="+start+">>"+"end 2 ="+end);String group1 = m.group(1); //返回aaa,返回第一組匹配到的子字串 String group2 = m.group(2); //返回2223,返回第二組匹配到的子字串 System.out.println("group1="+group1+">>"+"group2 ="+group2);}/** * split 按照指定的模式的匹配拆分給定輸入序列 */private static void split() {String regEx = "::";String str = "xd::abc::cde";Pattern p = Pattern.compile(regEx);String[] arr = p.split(str);// 執 行後,r就是{"xd","abc","cde"},其實分割時還有跟簡單的方法:// String[] arr =str.split("::");for (int i = 0; arr != null && i < arr.length; i++) {System.out.println(arr[i]);}}/** * matches 匹配 * matches()對整個字串進行匹配,只有整個字串都匹配了才返回true */private static void matches(){boolean bol = Pattern.matches("\\d+","2223");//返回true System.out.println("bol1="+bol);bol =Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字串才能返回true,這裡aa不能匹配到 System.out.println("bol1="+bol);bol =Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字串才能返回true,這裡bb不能匹配到 System.out.println("bol1="+bol);}/** * lookingAt()對前面的字串進行匹配,只有匹配到的字串在最前面才返回true */private static void lookingAt(){Pattern p=Pattern.compile("\\d+"); Matcher m=p.matcher("22bb23"); boolean bool = m.lookingAt();//返回true,因為\d+匹配到了前面的22 System.out.println("bool="+bool);Matcher m2=p.matcher("aa2223"); m2.lookingAt();//返回false,因為\d+不能匹配前面的aa System.out.println("bool="+bool);}/** * find()對字串進行匹配,匹配到的字串可以在任何位置. */private static void find(){Pattern p=Pattern.compile("\\d+"); Matcher m=p.matcher("22bb23"); boolean flag = m.find();//返回true System.out.println("flag="+flag);Matcher m2=p.matcher("aa2223"); flag = m2.find();//返回true System.out.println("flag="+flag);Matcher m3=p.matcher("aa2223bb"); flag = m3.find();//返回true System.out.println("flag="+flag);Matcher m4=p.matcher("aabb"); flag = m4.find();//返回false System.out.println("flag="+flag);}}
1、尋找某個字元中符合指定Regex的字串
/** * @param args */public static void main(String[] args) {String regex = "[a]+";String target = "aswwaaabsvasra"; search(regex,target);}/** * 尋找 * @param regex指定的Regex * @param target 目標字串 */private static void search(String regex,String target) {// 通過compile()方法建立Pattern執行個體Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);// 通過match()建立Matcher執行個體Matcher matcher = pattern.matcher(target);while (matcher.find()){// 尋找符合pattern的字串System.out.println("The result is here :" + matcher.group() + "\n"+ "It starts from " + matcher.start() + " to "+ matcher.end() + ".\n");}}
2、替換和刪除
/** * @param args */public static void main(String[] args) {String regex = "a";String target = "aswwaaabsvasra";String replace = "#";// search(regex,target);replace(regex, target, replace);}/** * 替換/刪除 * @param regex * @param target * @param replace */private static void replace(String regex,String target,String replace) {Pattern p = Pattern.compile(regex);Matcher m = p.matcher(target);String s = m.replaceAll(replace);// String s = m.replaceFirst("a");// 如果寫成空串,既可達到刪除的功能,比如:// String s=m.replaceAll("");System.out.println("s=" + s);}
Regex的構造摘要
字元
x 字元 x
\\ 反斜線字元
\0n 帶有八進位值 0 的字元 n (0 <= n <= 7)
\0nn 帶有八進位值 0 的字元 nn (0 <= n <= 7)
\0mnn 帶有八進位值 0 的字元 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 帶有十六進位值 0x 的字元 hh
\uhhhh 帶有十六進位值 0x 的字元 hhhh
\t 定位字元 ('\u0009')
\n 新行(換行)符 ('\u000A')
\r 斷行符號符 ('\u000D')
\f 換頁符 ('\u000C')
\a 警示 (bell) 符 ('\u0007')
\e 轉義符 ('\u001B')
\cx 對應於 x 的控制符
字元類
[abc] a、b 或 c(簡單類)
[^abc] 任何字元,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,兩頭的字母包括在內(範圍)
[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](減去)
預定義字元類
. 任何字元(與行結束符可能匹配也可能不匹配)
\d 數字:[0-9]
\D 非數字: [^0-9]
\s 空白字元:[ \t\n\x0B\f\r]
\S 非空白字元:[^\s]
\w 單詞字元:[a-zA-Z_0-9]
\W 非單詞字元:[^\w]
邊界匹配器
^ 行的開頭
$ 行的結尾
\b 單詞邊界
\B 非單詞邊界
\A 輸入的開頭
\G 上一個匹配的結尾
\Z 輸入的結尾,僅用於最後的結束符(如果有的話)
\z 輸入的結尾
Greedy 數量詞
X? X,一次或一次也沒有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超過 m 次
Reluctant 數量詞
X?? X,一次或一次也沒有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超過 m 次
Possessive 數量詞
X?+ X,一次或一次也沒有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超過 m 次
Logical 運算子
XY X 後跟 Y
X|Y X 或 Y
(X) X,作為擷取的群組
Back 引用
\n 任何匹配的 nth 擷取的群組
反斜線、轉義和引用
反斜線字元 ('\') 用於引用轉義構造,如上表所定義的,同時還用於引用其他將被解釋為非轉義構造的字元。因此,運算式 \\ 與單個反斜線匹配,而 \{ 與左括弧匹配。
在不表示轉義構造的任何字母字元前使用反斜線都是錯誤的;它們是為將來擴充Regex語言保留的。可以在非字母字元前使用反斜線,不管該字元是否非轉義構造的一部分。
根據 Java Language Specification 的要求,Java 原始碼的字串中的反斜線被解釋為 Unicode 轉義或其他字元轉義。因此必須在字串字面值中使用兩個反斜線,表示Regex受到保護,不被 Java 位元組碼編譯器解釋。例如,當解釋為Regex時,字串字面值 "\b" 與單個退格字元匹配,而 "\\b" 與單詞邊界匹配。字串字面值 "\(hello\)" 是非法的,將導致編譯時間錯誤;要與字串 (hello) 匹配,必須使用字串字面值 "\\(hello\\)"。