1. 程式人生 > >java 如何用pattern 和 Matcher 來使用正則表示式

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