Java 教程

Java 控制語句

面向物件程式設計

Java 內建類

Java 檔案處理

Java 錯誤和異常

Java 多執行緒

Java 同步

Java 網路

Java 集合

Java 介面

Java 資料結構

Java 集合演算法

高階 Java

Java 雜項

Java API 和框架

Java 類參考

Java 有用資源

Java - 正則表示式



Java 提供了 java.util.regex 包用於使用正則表示式進行模式匹配。Java 正則表示式與 Perl 程式語言非常相似,並且非常容易學習。

Java 中的正則表示式

正則表示式是用於匹配或查詢其他字串或字串集的特殊字元序列,使用包含在模式中的專門語法。它們可用於搜尋、編輯或處理文字和資料。

Java 正則表示式 (Regex) 類

java.util.regex 包主要包含以下三個類 -

  • Pattern 類 - Pattern 物件是正則表示式的編譯表示形式。Pattern 類沒有提供公共建構函式。要建立模式,您必須首先呼叫其公共靜態 compile() 方法之一,然後該方法將返回一個 Pattern 物件。這些方法接受正則表示式作為第一個引數。

  • Matcher 類 - Matcher 物件是解釋模式並對輸入字串執行匹配操作的引擎。與 Pattern 類一樣,Matcher 沒有定義公共建構函式。您可以透過在 Pattern 物件上呼叫 matcher() 方法來獲取 Matcher 物件。

  • PatternSyntaxException - PatternSyntaxException 物件是一個未經檢查的異常,表示正則表示式模式中的語法錯誤。

正則表示式中的捕獲組

捕獲組是一種將多個字元視為單個單元的方法。它們是透過將要分組的字元放在一組括號內建立的。例如,正則表示式 (dog) 建立了一個包含字母“d”、“o”和“g”的單個組。

捕獲組的編號是透過從左到右計算其開括號來確定的。例如,在表示式 ((A)(B(C))) 中,有四個這樣的組 -

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

要找出表示式中存在多少個組,請在 matcher 物件上呼叫 groupCount 方法。groupCount 方法返回一個 int,表示匹配器模式中存在的捕獲組的數量。

還有一個特殊的組,組 0,它始終表示整個表示式。groupCount 報告的總數不包括此組。

示例

以下示例說明如何從給定的字母數字字串中查詢數字字串 -

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

public class RegexMatches {

   public static void main( String args[] ) {
      // String to be scanned to find the pattern.
      String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";

      // Create a Pattern object
      Pattern r = Pattern.compile(pattern);

      // Now create matcher object.
      Matcher m = r.matcher(line);
      if (m.find( )) {
         System.out.println("Found value: " + m.group(0) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
      }else {
         System.out.println("NO MATCH");
      }
   }
}

輸出

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

正則表示式語法

以下是 Java 中所有可用正則表示式元字元語法的列表 -

子表示式 匹配
^ 匹配行首。
$ 匹配行尾。
. 匹配任何單個字元,但換行符除外。使用 m 選項允許它匹配換行符。
[...] 匹配括號中任何單個字元。
[^...] 匹配括號中任何單個字元。
\A 整個字串的開頭。
\z 整個字串的結尾。
\Z 整個字串的結尾,除了允許的最終行終止符。
re* 匹配前一個表示式的 0 個或多個出現。
re+ 匹配前一個表示式的 1 個或多個出現。
re? 匹配前一個表示式的 0 個或 1 個出現。
re{ n} 精確匹配前一個表示式的 n 個出現。
re{ n,} 匹配前一個表示式的 n 個或更多出現。
re{ n, m} 至少匹配前一個表示式的 n 個出現,最多 m 個出現。
a| b 匹配 a 或 b。
(re) 對正則表示式進行分組並記住匹配的文字。
(?: re) 對正則表示式進行分組,但不記住匹配的文字。
(?> re) 匹配不回溯的獨立模式。
\w 匹配單詞字元。
\W 匹配非單詞字元。
\s 匹配空白字元。等效於 [\t\n\r\f]。
\S 匹配非空白字元。
\d 匹配數字。等效於 [0-9]。
\D 匹配非數字。

\A 匹配字串的開頭。
\Z 匹配字串的結尾。如果存在換行符,則匹配換行符之前的字元。
\z 匹配字串的結尾。
\G 匹配上次匹配結束的位置。
\n 反向引用捕獲組編號為“n”的組。
\b 在括號外部匹配單詞邊界。在括號內部匹配退格鍵 (0x08)。
\B 匹配非單詞邊界。
\n, \t, 等。 匹配換行符、回車符、製表符等。
\Q 轉義(引用)直到 \E 之前的所有字元。
\E 結束以 \Q 開始的引用。

正則表示式 - Matcher 類方法

以下是有用的例項方法列表:

索引方法

索引方法提供有用的索引值,精確地顯示匹配在輸入字串中的位置:

序號 方法及描述
1

public int start()

返回上一次匹配的起始索引。

2

public int start(int group)

返回在上一次匹配操作期間由給定組捕獲的子序列的起始索引。

3

public int end()

返回匹配到的最後一個字元之後的偏移量。

4

public int end(int group)

返回在上一次匹配操作期間由給定組捕獲的子序列的最後一個字元之後的偏移量。

研究方法

研究方法檢查輸入字串並返回一個布林值,指示是否找到模式:

序號 方法及描述
1

public boolean lookingAt()

嘗試從區域的開頭開始,將輸入序列與模式進行匹配。

2

public boolean find()

嘗試查詢輸入序列中與模式匹配的下一個子序列。

3

public boolean find(int start)

重置此匹配器,然後嘗試查詢輸入序列中與模式匹配的下一個子序列,從指定的索引開始。

4

public boolean matches()

嘗試將整個區域與模式進行匹配。

正則表示式 - 替換方法

替換方法是用於替換輸入字串中文字的有用方法:

序號 方法及描述
1

public Matcher appendReplacement(StringBuffer sb, String replacement)

實現一個非終端的追加和替換步驟。

2

public StringBuffer appendTail(StringBuffer sb)

實現一個終端的追加和替換步驟。

3

public String replaceAll(String replacement)

將輸入序列中與模式匹配的每個子序列替換為給定的替換字串。

4

public String replaceFirst(String replacement)

將輸入序列中與模式匹配的第一個子序列替換為給定的替換字串。

5

public static String quoteReplacement(String s)

返回指定字串的文字替換字串。此方法生成一個字串,該字串將在 Matcher 類的 appendReplacement 方法中用作文字替換s

start 和 end 方法

以下示例計算單詞“cat”在輸入字串中出現的次數:

示例

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

public class RegexMatches {

   private static final String REGEX = "\\bcat\\b";
   private static final String INPUT = "cat cat cat cattie cat";

   public static void main( String args[] ) {
      Pattern p = Pattern.compile(REGEX);
      Matcher m = p.matcher(INPUT);   // get a matcher object
      int count = 0;

      while(m.find()) {
         count++;
         System.out.println("Match number "+count);
         System.out.println("start(): "+m.start());
         System.out.println("end(): "+m.end());
      }
   }
}

輸出

Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

您可以看到,此示例使用單詞邊界來確保字母“c” “a” “t”不僅僅是較長單詞中的子字串。它還提供了一些關於匹配發生在輸入字串中的哪個位置的有用資訊。

start 方法返回在上一次匹配操作期間由給定組捕獲的子序列的起始索引,而 end 返回匹配到的最後一個字元的索引加一。

matches() 和 lookingAt() 方法

matches 和 lookingAt 方法都嘗試將輸入序列與模式進行匹配。但是,區別在於 matches 要求匹配整個輸入序列,而 lookingAt 則不需要。

兩種方法始終從輸入字串的開頭開始。以下示例解釋了其功能:

示例

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

public class RegexMatches {

   private static final String REGEX = "foo";
   private static final String INPUT = "fooooooooooooooooo";
   private static Pattern pattern;
   private static Matcher matcher;

   public static void main( String args[] ) {
      pattern = Pattern.compile(REGEX);
      matcher = pattern.matcher(INPUT);

      System.out.println("Current REGEX is: "+REGEX);
      System.out.println("Current INPUT is: "+INPUT);

      System.out.println("lookingAt(): "+matcher.lookingAt());
      System.out.println("matches(): "+matcher.matches());
   }
}

輸出

Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

replaceFirst() 和 replaceAll() 方法

replaceFirst 和 replaceAll 方法替換與給定正則表示式匹配的文字。顧名思義,replaceFirst 替換第一個出現的匹配項,而 replaceAll 替換所有出現的匹配項。

以下示例解釋了其功能:

示例

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

public class RegexMatches {

   private static String REGEX = "dog";
   private static String INPUT = "The dog says meow. " + "All dogs say meow.";
   private static String REPLACE = "cat";

   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      
      // get a matcher object
      Matcher m = p.matcher(INPUT); 
      INPUT = m.replaceAll(REPLACE);
      System.out.println(INPUT);
   }
}

輸出

The cat says meow. All cats say meow.

appendReplacement() 和 appendTail() 方法

Matcher 類還為文字替換提供 appendReplacement 和 appendTail 方法。

以下示例解釋了其功能:

示例

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

public class RegexMatches {

   private static String REGEX = "a*b";
   private static String INPUT = "aabfooaabfooabfoob";
   private static String REPLACE = "-";
   public static void main(String[] args) {

      Pattern p = Pattern.compile(REGEX);
      
      // get a matcher object
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();
      while(m.find()) {
         m.appendReplacement(sb, REPLACE);
      }
      m.appendTail(sb);
      System.out.println(sb.toString());
   }
}

輸出

-foo-foo-foo-

正則表示式 - PatternSyntaxException 類方法

PatternSyntaxException 是一個未經檢查的異常,表示正則表示式模式中的語法錯誤。PatternSyntaxException 類提供以下方法來幫助您確定問題所在:

序號 方法及描述
1

public String getDescription()

檢索錯誤的描述。

2

public int getIndex()

檢索錯誤索引。

3

public String getPattern()

檢索錯誤的正則表示式模式。

4

public String getMessage()

返回一個多行字串,其中包含語法錯誤及其索引的描述、錯誤的正則表示式模式以及模式中錯誤索引的可視指示。

廣告