java 如何用pattern 和 Matcher 來使用正則表示式
java的regex庫
java裡預留了一個regex庫,方便於我們在java裡操作正則表示式,或者用它來匹配字串。
其中比較常用的就是 Pattern 和 Matcher ,pattern是一個編譯好的正則表示式,而Mather是一個正則表示式介面卡,Mather的功能很強大,所以我們一般用pattern 來獲取一個Matcher物件,然後用Matcher來操作正則表示式。先看一下這兩個類的用法吧、 Pattern
建立pattern的物件是很簡單的,但是由於pattern的構造方法是用private宣告的,所以我們僅能通過工廠模式的compile方法來返回一個Pattern的物件。
Pattern pattern = Pattern.compile("[abc]");
compile可以接收一個正則表示式作為引數。
接下來我們建立一個Matcher物件。Matcher的構造方法也是一個private方法,但是我們可以通過Pattern的Matcher方法來返回一個Matcher物件。
Matcher matcher = pattern.matcher("hello abc");
這裡matcher可以接收一個字串作為引數,準確的說這裡所接收的引數型別是CharSequences介面型別的引數,但是String、StringBuffer、StringBuilder還有CharBuffer都實現了CharSequence介面,因此我們向裡面傳入這四種任何我們需要的引數。
與此同時Pattern還提供了一個matches 靜態方法,它允許我們傳入一個String型別的正則表示式和一個String型別的需要匹配的字串,並返回一個boolean型別的值,這個方法的好處在於我們可以不用建立pattern物件和matcher物件就可以知道所傳入的正則表示式能不能匹配所傳入的字串。
boolean bool = Pattern.matches("\\w+","hello abc");
Watcher
說到Wather,這個東西就很強大了,我們比較常用的方法有:
find(); group();
(1)先來說一下find()和group這兩個方法。 find有點像一個迭代器,它能通過正則表示式向前迭代。 下來看一個例子
public class Main {
public static void main(String[] args){
Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher("hello abc bbc cbc ccc");
//find向前迭代
while(matcher.find()){
System.out.println(matcher.group());
}
}
}
我們先來看看jdk給出的api怎麼定義find的; boolean find(); 可以知道find返回的是一個boolean值,當前方沒有內容的時候,find會返回false,所以我們這裡可以直接用while來寫,這句程式碼打印出的內容是
hello
abc
bbc
cbc
ccc
可以看到其實我們的正則表示式"\w+"只匹配到了第一個單詞hello ,但是因為find迭代的關係,把後面的單詞全部都打印出來了,參照的正是我們給出的正則表示式。
(2)group 說到find就不得不說group。 下面看個式子
(a(b)(c(d)))
這裡的話我們把整個式子稱為第0組, 第一組是 a(b)(c(d)) 第二組是 子式 b 和 子式c(d) 第三組是 d
看一下幾個group方法 int groupCount() 返回此匹配器模式中的捕獲組數 這個方法也就是返回所匹配的字串的組數。
public class Main {
public static void main(String[] args){
Pattern pattern = Pattern.compile("(\\w+)\\d+");
Matcher matcher = pattern.matcher("hello123 abc bbc cbc ccc");
matcher.find();
System.out.println(matcher.groupCount());
}
}
這裡匹配到的是hello123, 當然不加()也能得到,這裡只是為了方便演示。 打印出來的數值是1,這是因為我們只有一個組
那group();呢
String group() 返回由以前匹配操作所匹配的輸入子序列。
也就是說group是返回所匹配到的第0組的值,返回值是一個String。這也能解釋我們剛剛用find進行迭代的那個例子了。
public class Main {
public static void main(String[] args){
Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher("hello abc bbc cbc ccc");
//find向前迭代
while(matcher.find()){
System.out.println(matcher.group());
}
}
}
這裡沒有分組所以直接將匹配到的String打印出來,其實也就是第0組.
另外 group還有個過載的方法,可以接收一個int型別的引數
String group(int group) 返回在以前匹配操作期間由給定組捕獲的輸入子序列。 傳入的引數正是組數.
public class Main {
public static void main(String[] args){
Pattern pattern = Pattern.compile("(\\w+)\\s\\d+");
Matcher matcher = pattern.matcher("hello 123 abc bbc cbc ccc");
matcher.find();
System.out.println(matcher.group(1));
}
}
打印出來的結果正在我們的意料之中是hello。
除此之外還有兩個可以返回匹配當前字串的索引的方法。
int start(); int end();
其中start是返回匹配成功的子串的第一個字母的索引,而end是返回子串最後一個索引的位置+1.
String input = "hello abc BBc Cbc ccc";
Matcher matcher = Pattern.compile("[A-Z][A-Z]\\w").matcher(input);
matcher.find();
System.out.println(input.charAt(matcher.start()));
這裡打印出來的值是B。但是如果我們換成end就不一樣了。
System.out.println(input.charAt(matcher.end()));
這裡打印出來的值卻是“ ”是一個空字元,也就是c的索引加了1,所以我們這裡只需稍作修改便可以打印出c了。
System.out.println(input.charAt(matcher.end()-1));
matcher 和 lookingAt
這兩個方法都返回一個boolean值,不同的是matcher是將整個輸入序列拿去匹配,而lookingAt一旦匹配成功一個子串就返回true。
public class Main {
public static void main(String[] args){
String s="aaaaaaaaaabbbbbbbbb";
Matcher matcher = Pattern.compile("a+").matcher(s);
System.out.println(matcher.lookingAt());//true
}
}
這裡匹配到的是aaaaaaaaaaa,因為用的是lookingAt,所以直接返回true了
如果換做是matches()。
System.out.println(matcher.matches());//false
即返回false