java 正則表達式獲取大括號之間的內容

先說下組的概念:java

捕獲組

捕獲組是把多個字符當一個單獨單元進行處理的方法,它經過對括號內的字符分組來建立。正則表達式

例如,正則表達式 (dog) 建立了單一分組,組裏包含"d","o",和"g"。spa

捕獲組是經過從左至右計算其開括號來編號。例如,在表達式((A)(B(C))),有四個這樣的組:翻譯

  • ((A)(B(C)))
  • (A)
  • (B(C))
  • (C)

能夠經過調用 matcher 對象的 groupCount 方法來查看錶達式有多少個分組。groupCount 方法返回一個 int 值,表示matcher對象當前有多個捕獲組。code

還有一個特殊的組(group(0)),它老是表明整個表達式。該組不包括在 groupCount 的返回值中。對象

Java正則表達式匹配模式[貪婪型、勉強型、佔有型],默認狀況是貪婪模式匹配

貪婪模式表達式:three

表達式 含義
X? X,一次或一次也沒有
X* X,零次或屢次
X+ X,一次或屢次
X{n} X,剛好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,可是不超過 m 次

非貪婪模式表達式:文檔

表達式 含義
X?? X,一次或一次也沒有
X*? X,零次或屢次
X+? X,一次或屢次
X{n}? X,剛好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,可是不超過 m 次

對於這三種匹配模式也有叫: 「最大匹配Greedy」「最小匹配Reluctant」「徹底匹配Possessive」。如今將我對這三種匹配模式的理解寫出來,並提供一些例子供你們參考。字符串

一、Greediness(貪婪型): 最大匹配table

X?、X*、X+、X{n,}都是最大匹配。例如你要用「<.+>」去匹配「a<tr>aava </tr>abb」,也許你所期待的結果是想匹配「<tr>」,可是實際結果卻會匹配到「<tr>aava </tr>」。這是爲何呢?下面咱們跟蹤下最大匹配的匹配過程。

①「<」匹配字符串的「<」。

②「.+」匹配字符串的「<tr>aava </tr>ab」,在進行最大匹配時,它把兩個「>」都匹配了,它匹配了全部字符,直到文本的最後字符「b」

③這時,發現不能成功匹配「>」,開始按原路回退,用「a」與「>」匹配,直到「ab」前面的「>」匹配成功。

這就是最大匹配,咱們匹配的時候應該看最後面能匹配到哪。

代碼示例:
String test = "a<tr>aava </tr>abb ";
String reg = "<.+>";
System.out.println(test.replaceAll(reg, "###"));
輸出:

a###abb

二、Reluctant(Laziness)(勉強型):最小匹配

X?、X*、X+、X{n,}都是最大匹配。好,加個?就成了Laziness匹配。例如X??、X*?、X+?、X{n,}?都是最小匹配,其實X{n,m}?和X{n }?有些多餘。

最小匹配意味者,.+? 匹配一個字符後,立刻試一試>的匹配可能,失敗了,則.+? 再匹配一個字符,再立刻試一試>的匹配可能。JDK文檔中Greedy 和 Reluctant,它是以eat一口來隱喻的,因此翻譯成貪吃和(勉強的)厭食最貼切了。不過我喜歡最大匹配、最小匹配的說法。

代碼示例:
String test = "a<tr>aava </tr>abb ";
String reg = "<.+?>";
System.out.println(test.replaceAll(reg, "###"));
輸出:
a###aava ###abb
和上面的不一樣是匹配了兩處。

三、Possessive(佔有型):徹底匹配

與最大匹配不一樣,還有一種匹配形式:X?+、X*+、X++、X{n,}+等,成爲徹底匹配。它和最大匹配同樣,一直匹配全部的字符,直到文本的最後,但它不禁原路返回。也就是說,一口匹配,搞不定就算了,到也乾脆,偶喜歡。

代碼示例:
String test = "a<tr>aava </tr>abb ";
String test2 = "<tr>";
String reg = "<.++>";
String reg2 = "<tr>";
System.out.println(test.replaceAll(reg, "###"));
System.out.println(test2.replaceAll(reg2, "###"));
輸出:
a<tr>aava </tr>abb
###

可見。徹底匹配是最嚴格的,必須整個字符串匹配才行。

實例: 獲取下面字符串中的大括號中的內容:

{one}{two}{three}

能夠這樣:

String s  = "{one}{two}{three}";
//由於默認爲貪婪模式,因此若是沒有使用顯示()組中的元素不能爲大括號([^}]*),而是使用(.*),
//那麼會匹配的字符串爲:one}{two}{three
Pattern p = Pattern.compile("\\{([^}]*)\\}");
Matcher m = p.matcher(s);
while (m.find()) {
  System.out.println(m.group(1));//第一次匹配成功是one,第二次匹配成功是two,第三次匹配爲three
}

輸出

one
two
three

若是想要三個大括號中的 內容一塊兒輸出,能夠這樣:

String s  = "{one}{two}{three}";
Pattern p = Pattern.compile("\\{([^}]*)\\}\\{([^}]*)\\}\\{([^}]*)\\}");
Matcher m = p.matcher(s);
while (m.find()) {
  System.out.println(m.group(1) + ", " + m.group(2) + ", " + m.group(3));//獲取該次匹配中組(),正則表達式中只有一個(),即只分了一個組
}

輸出

one, two, three

關於組的實例:

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 pattern = "(\\D*)(\\d+)(.*)";
 
      // 建立 Pattern 對象
      Pattern r = Pattern.compile(pattern);
 
      // 如今建立 matcher 對象
      Matcher m = r.matcher(line);
      if (m.find( )) {
         //每次匹配成功以後,表示利用pattern 獲取到了匹配的字符串,而pattern 中有三個小括號,即有三個
         //組,那麼每次匹配成功確定有group(1),group(2),group(3),group(0)是它老是表明整個表達式
         System.out.println("Found value: " + m.group(0) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
         System.out.println("Found value: " + m.group(3) ); 
      } else {
         System.out.println("NO MATCH");
      }
   }
}

運行結果以下:

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?
相關文章
相關標籤/搜索