正則表達式是一種強大而靈活的文本處理工具。使用正則表達式,我們能夠以編程的方式,構造複雜的文本模式,並對輸入的字符串進行搜索,一旦找到了匹配這些模式的部分,我們就可以隨心所欲的對他們進行處理。正則表達式是一種簡潔、動態的語言,除了語法是一個難點之外。
正則表達式提供了一種完全通用的方式,能夠解決各種字符串處理相關的問題,包括:匹配、選擇、編輯以及驗證。
Java正則表達式通過java.util.regex包下的Pattern和Matcher類實現。
java.util.regex是一個用正則表達式所訂製的模式來對字符串進行匹配工作的類庫包。它包括兩個類:Pattern和Matcher。
Pattern: Pattern是一個正則表達式經編譯後的表現模式。
Matcher :Matcher對象是一個狀態機器,它依據Pattern對象做爲匹配模式對字符串展開匹配檢查。
首先一個Pattern實例訂製了一個所用語法與PERL(一種擁有各種語言功能的夢幻腳本語言)的類似的正則表達式經編譯後的模式,也可以說是創建一個匹配模式,然後一個Matcher實例在這個給定的Pattern實例的模式控制下進行字符串的匹配工作。
Pattern類可以通過兩個靜態方法創建:compile(String regex)和compile(String regex,int flags),其中regex是正則表達式,flags爲可選模式(如:Pattern.CASE_INSENSITIVE 忽略大小寫)
實例:
Pattern pattern = Pattern.compile(".*/hello/.{1,}");
System.out.println(pattern.pattern());//返回此模式的正則表達式即.*/hello/.{1,}
應用正則表達式最簡單的途徑,是利用String類內建的功能:
System.out.println("-123456".matches("-?\\d+"));//返回true
System.out.println("+911".matches("-?\\d+"));//返回false
Pattern類還自帶了一個非常有用的正則表達式工具:split()方法,其功能是“將字符串從正則表達式匹配的地方切開”,該方法有兩種實現:
Pattern.split(CharSequence input) :
Pattern pattern = Pattern.compile(" ");
String str = "hello world hello world";
String [] array = pattern.split(str);
for(String s:array ) {
System.out.println(s);
}
//輸出
-->hello
-->world
-->hello
-->world
Pattern.split(CharSequence input, int limit),其中limit爲返回元素的個數:
實例:
Pattern pattern = Pattern.compile(" ");
String str = "hello world hello world";
String [] array = pattern.split(str,2);
for(String s:array ) {
System.out.println(s);
}
//輸出
-->hello
-->world hello world
在細說一下Pattern.split(CharSequence input, int limit),當limit值大於所能返回的字符串的最多個數或者爲負數,返回的字符串個數將不受限制,但結尾可能包含空串,而當limit=0時與Pattern.split(CharSequence input)等價,但結尾的空串會被丟棄。
我們可以使用Pattern類的split方法實現切割字符串,其實String類也自帶split()方法,String類的split()方法也有兩種實現:
String.split(String regex):
String str = "hello world hello world";
String [] arr = str.split(" ");
for(String st:arr ) {
System.out.println("--->"+st);
}
//輸出
--->hello
--->world
--->hello
--->world
String.split(String regex, int limit):
String str = "hello world hello world";
String [] arr = str.split(" ",2);
for(String st:arr ) {
System.out.println("--->"+st);
}
//輸出
--->hello
--->world hello world
除了split()切割方法之外,String類還自帶了一個正則表達式的工具:替換
//替換所有的子串
System.out.println(str.replaceAll("o", "0"));
//替換第一個匹配的子串
System.out.println(str.replaceFirst("o", "0"));
//輸出
-->hell0 w0rld hell0 w0rld
-->hell0 world hello world
Pattern類也自帶一個靜態匹配方法matches(String regex, CharSequence input),但只能進行全字符串匹配並且只能返回是否匹配上的boolean值
實例:
String s= "hello";
String str= "hello world hello world";
System.out.println(Pattern.matches("hello",s));//返回true
System.out.println(Pattern.matches("hello",str));//返回false
比起功能有限的String類,我們更願意去構建一個功能強大的正則表達式對象,這裏就需要引入Matcher類了,Pattern類中的matcher(CharSequence input)會返回一個Matcher對象。
Matcher類提供了對正則表達式的分組支持,以及對正則表達式的多次匹配支持,要想得到更豐富的正則匹配操作,那就需要將Pattern與Matcher聯合使用。
Matcher類常用的返回boolean值得匹配方法有:
Pattern pattern = Pattern.compile("hello");
String str = "hello world hello world";
String s = "hello";
Matcher matcher = pattern.matcher(str);
//嘗試查找與該模式匹配的輸入序列的下一個子序列
System.out.println("--->"+matcher.find());//--->true
//嘗試查找匹配該模式、從指定索引開始的輸入序列的下一個子序列
System.out.println("--->"+matcher.find(1));//--->true
System.out.println("--->"+matcher.find(15));//--->false
//嘗試將從區域開頭開始的輸入序列與該模式匹配。
System.out.println("--->"+matcher.lookingAt());//--->true
//嘗試將整個區域與模式匹配。
System.out.println("--->"+matcher.matches());//--->false
Matcher matcher1 = pattern.matcher(s);
System.out.println("--->"+matcher1.matches());//--->true
這裏介紹下組的概念:組是用括號劃分的正則表達式,可以根據組的編號來引用這個組。組號爲0表示整個表達式,組號爲1表示被第一對括號括起的組,依次類推,例如A(B©)D,組0是ABCD,組1是BC,組2是C。
Matcher類提供了start(),end(),group()分別用於返回字符串的起始索引,結束索引,以及匹配到到的字符串。
實例:
Pattern pattern = Pattern.compile("hello");
String str = "hello world hello world";
String s = "hello";
Matcher matcher = pattern.matcher(str);
matcher.find();
//返回以前匹配的初始索引
System.out.println("--->"+matcher.start());//--->0
//返回最後匹配字符之後的偏移量
System.out.println("--->"+matcher.end());//--->5
//返回由以前匹配操作所匹配的輸入子序列
System.out.println("--->"+matcher.group());//--->hello
Matcher類提供了start(int gropu),end(int group),group(int i),groupCount()用於分組操作
實例:
Pattern pattern = Pattern.compile("(hello )(world)");
String str = "hello world hello world";
Matcher matcher = pattern.matcher(str);
matcher.find();
//返回此匹配器模式中的捕獲組數
System.out.println("--->"+matcher.groupCount());//--->2
//返回在以前匹配操作期間由給定組捕獲的輸入子序列
System.out.println("--->"+matcher.group(1));//--->hello
//返回在以前匹配操作期間由給定組捕獲的輸入子序列
System.out.println("--->"+matcher.group(2));//--->world
//返回在以前的匹配操作期間,由給定組所捕獲的子序列的初始索引
System.out.println("--->"+matcher.start(1));//--->0
//返回在以前的匹配操作期間,由給定組所捕獲子序列的最後字符之後的偏移量
System.out.println("--->"+matcher.end(1));//--->6
//返回在以前的匹配操作期間,由給定組所捕獲的子序列的初始索引
System.out.println("--->"+matcher.start(2));//--->6
//返回在以前的匹配操作期間,由給定組所捕獲子序列的最後字符之後的偏移量
System.out.println("--->"+matcher.end(2));//--->11
Matcher類提供了兩種用於重置當前匹配器的方法:reset()和reset(CharSequence input)
Pattern pattern = Pattern.compile("hello");
String str = "hello world hello world";
Matcher matcher = pattern.matcher(str);
matcher.find();
System.out.println("--->"+matcher.group());//--->hello
//重置匹配器
matcher.reset();
matcher.find();
System.out.println("--->"+matcher.group());//--->hello
//重置此具有新輸入序列的匹配器
matcher.reset("world");
System.out.println(matcher.find());//返回false
上面我們看到的例子都是將正則表達式應用於靜態字符串中,下面我們主要演示一下正則表達式在Java/IO中的應用:
讀取本地文件實例:
Pattern pattern = Pattern.compile("hello");
Matcher matcher = null;
try {
StringBuilder sb = new StringBuilder();
BufferedReader in = new BufferedReader(new FileReader(new File("D:\\launchfile.txt").getAbsoluteFile()));
String line;
while( (line = in.readLine()) != null ){
matcher = pattern.matcher(line);
if(matcher.find()) {
sb.append(line);
sb.append("\n");
}
}
System.out.println(sb.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
掃描輸入實例:
System.out.println("請輸入您希望檢索的數據:");
Scanner scanner = new Scanner(System.in);
String pattern ="hello";
while(scanner.hasNext(pattern)) {
scanner.next(pattern);
MatchResult match = scanner.match();
System.out.println(match.group());
}