[正則表達式]正則表達式(.*)和(.*?)的字符串匹配問題

Java 正則表達式
正則表達式定義了字符串的模式。
正則表達式可以用來搜索、編輯或處理文本。
正則表達式並不僅限於某一種語言,但是在每種語言中有細微的差別。
Java正則表達式和Perl的是最爲相似的。
java.util.regex包主要包括以下三個類:

  • Pattern類:
    pattern對象是一個正則表達式的編譯表示。Pattern類沒有公共構造方法。要創建一個Pattern對象,你必須首先調用其公共靜態編譯方法,它返回一個Pattern對象。該方法接受一個正則表達式作爲它的第一個參數。
  • Matcher類:
    Matcher對象是對輸入字符串進行解釋和匹配操作的引擎。與Pattern類一樣,Matcher也沒有公共構造方法。你需要調用Pattern對象的matcher方法來獲得一個Matcher對象。
  • PatternSyntaxException:
    PatternSyntaxException是一個非強制異常類,它表示一個正則表達式模式中的語法錯誤。

捕獲組
捕獲組是把多個字符當一個單獨單元進行處理的方法,它通過對括號內的字符分組來創建。
例如,正則表達式(dog) 創建了單一分組,組裏包含”d”,”o”,和”g”。
捕獲組是通過從左至右計算其開括號來編號。例如,在表達式((A)(B(C))),有四個這樣的組:
1. ((A)(B(C)))
2. (A)
3. (B(C))
4. (C)
可以通過調用matcher對象的groupCount方法來查看表達式有多少個分組。groupCount方法返回一個int值,表示matcher對象當前有多個捕獲組。
還有一個特殊的組(組0),它總是代表整個表達式。該組不包括在groupCount的返回值中
實例
下面的例子說明如何從一個給定的字符串中找到數字串:

  1. (.*)正則表達式:
String regular = "(.*)(\\d+)(.*)";
//第一個分組是(.*),第二個分組是(\\d+),第三個分組是(.*)
package com.clfeng.regularExpression;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

    public static void main(String[] args) {
        // 按制定模式在字符串中查找
        String line = "This order was placed for QT3000! OK?";
        String regular = "(.*)(\\d+)(.*)";

        // 創建pattern對象
        Pattern pattern = Pattern.compile(regular);

        // 創建matcher對象
        Matcher matcher = pattern.matcher(line);

        if (matcher.find()) {
            System.out.println("Found value:" + matcher.group(0));
            System.out.println("Found value:" + matcher.group(1));
            System.out.println("Found value:" + matcher.group(2));
            System.out.println("Found value:" + matcher.group(3));
        }
    }
}

運行結果
Found value:This order was placed for QT3000! OK?
Found value:This order was placed for QT300
Found value:0
Found value:! OK?

2 (.*?)正則表達式

String regular = "(.*?)(\\d+)(.*)";
//第一個分組是(.*?),第二個分組是(\\d+),第三個分組是(.*)
package com.clfeng.regularExpression;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

    public static void main(String[] args) {
        // 按制定模式在字符串中查找
        String line = "This order was placed for QT3000! OK?";
        String regular = "(.*?)(\\d+)(.*)";

        // 創建pattern對象
        Pattern pattern = Pattern.compile(regular);

        // 創建matcher對象
        Matcher matcher = pattern.matcher(line);

        if (matcher.find()) {
            System.out.println("Found value:" + matcher.group(0));
            System.out.println("Found value:" + matcher.group(1));
            System.out.println("Found value:" + matcher.group(2));
            System.out.println("Found value:" + matcher.group(3));
        }
    }
}

運行結果
Found value:This order was placed for QT3000! OK?
Found value:This order was placed for QT
Found value:3000
Found value:! OK?

結果分析:

  1. (.*)正則表達式
    (.*)涉及到貪婪模式。當正則表達式中包含能接受重複的限定符時,通常的行爲是(在使整個表達式能得到匹配的前提下)匹配儘可能多的字符。以這個表達式爲例:a.*b,它將會匹配最長的以a開始,以b結束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱爲貪婪匹配。所以第一個程序第一個分組匹配的的結果是Found value:This order was placed for QT300,儘可能匹配多的字符(因爲第二組還要匹配數字,所以匹配到300)

  2. (.*?)正則表達式
    有時,我們更需要懶惰匹配,也就是匹配儘可能少的字符。前面給出的限定符都可以被轉化爲懶惰匹配模式,只要在它後面加上一個問號?。這樣.?就意味着匹配任意數量的重複,但是在能使整個匹配成功的前提下使用最少的重複。a.?b匹配最短的,以a開始,以b結束的字符串。如果把它應用於aabab的話,它會匹配aab(第一到第三個字符)和ab(第四到第五個字符)。所以第二個程序的第一個分組匹配的的結果是Found value:This order was placed for QT,匹配儘可能少的字符(因爲第二組還要匹配數字,所以匹配到QT)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章